**- Undocumented Matlab - https://undocumentedmatlab.com -**

Function definition meta-info

Posted By Yair Altman On September 4, 2013 | __6 Comments__

Last week, Loren Shure posted an article ^{[1]} explaining some documented ways to retrieve information about the type of Matlab functions. Loren basically showed how we can use a combination of the built-in * nargin* and

Today I will discuss several additional alternatives for retrieving information about a specified function:

**mtree**^{[2]}**getcallinfo**^{[3]}**mlint**^{[4]}**which**^{[5]}**functions**^{[6]}

Reader Mark Brown has commented ^{[7]} about an alternative, using the semi-documented built-in function * mtree*:

```
>> t = mtree('mtree.m','-file'); t.select(1).kind % m-class file
ans =
CLASSDEF
>> t = mtree('profile.m','-file'); t.select(1).kind % regular m-file function
ans =
FUNCTION
>> t = mtree('test.m','-file'); t.select(1).kind % script file
ans =
EXPR
```

* mtree* contains numerous other goodies in its reported parse-tree, including information about who-calls-what-where, set/used info about variables and other information used in the lexical parsing of the m-file.

Unlike many other internal m-files, which are much simpler, less well written and sparsely documented (if at all), but for which personal credit is included in a comment,

For people worried about future compatibility, note that

* getcallinfo* is another semi-documented internal function, which uses

```
>> getcallinfo('profile.m');
Name Type Starts Ends Length Full Name
---- ---- ------ ---- ------ ---------
profile function 1 242 242 profile
ParseInputs subfunction 247 354 82 profile>ParseInputs
ParseOption nested-function 262 287 26 profile>ParseInputs/ParseOption
notifyUI subfunction 356 370 15 profile>notifyUI
>> s = getcallinfo('profile.m')
s =
1x4 struct array with fields:
type
name
fullname
functionPrefix
calls
firstline
lastline
linemask
>> s(4).calls
ans =
fcnCalls: [1x1 struct]
innerCalls: [1x1 struct]
dotCalls: [1x1 struct]
atCalls: [1x1 struct]
>> s(4).calls.fcnCalls
ans =
names: {'usejava'}
lines: 359
>> s(4).calls.innerCalls
ans =
names: {1x0 cell}
lines: [1x0 double]
>> s(4).calls.dotCalls
ans =
names: {'com.mathworks.mde.profiler.Profiler.start' [1x40 char] [1x41 char]}
lines: [363 365 367]
```

Note: In order to use * getcallinfo*, we first need to fix a small internal bug in

`displayStructure()`

sub-function. Modifying this file may require administrator privileges, and can be done in any text editor. The bug is that the keyword `length`

is used as a variable in this function (line #136 in R2013b), and so cannot be used to reference the built-in function ```
130: function displayStructure(strc)
...
136: length = getString(message('MATLAB:codetools:reports:RptLength'));
137: fullName = getString(message('MATLAB:codetools:reports:RptFullName'));
138:
139: fprintf('%-20s %-20s %-4s %-4s %-6s %-20s\n',name,type,starts,ends,length,fullName);
140: fprintf('%-20s %-20s %-4s %-4s %-6s %-20s\n', ...
...
145: getDashesForString(length), ...
146: getDashesForString(fullName));
147: for n = 1:numel(strc) % original code: n = 1:length(strc)
...
152: end
153: end
```

A few months ago, I wrote ^{[9]} about * mlint*‘s undocumented interface and ability to report much internal information about the analyzed file. It is no surprise that one of the undocumented

`-calls`

, which lists the calling-tree of an m-file. For example:```
>> mlint profile.m -calls
M0 1 14 profile
E0 242 3 profile
U1 122 15 callstats
U1 131 11 ParseInputs
U1 133 10 MException
U1 134 5 throw
U1 161 8 lower
U1 164 9 notifyUI
U1 165 23 true
U1 169 23 false
U1 180 9 profreport
U1 183 13 usejava
U1 184 13 error
U1 184 19 message
U1 188 21 profile
U1 189 16 isempty
U1 192 17 profview
U1 236 9 warning
S0 248 7 ParseInputs
E0 354 3 ParseInputs
U1 260 1 error
U1 260 7 nargchk
U1 260 17 Inf
U1 260 21 nargin
N1 262 23 ParseOption
E1 287 7 ParseOption
U2 263 12 strcmp
...
```

In this report, the first character represents the function type:

- M = main (top-level) function
- S = sub-function
- N = nested function
- U = out-of-scope (external/built-in) function
- A = anonymous function
- E = end-of-function indication

The following numbers indicate the nesting level, line #, column # and function identifier (name). In essence, it’s the same information presented by * getcallinfo*, with two distinctions:

In this regard, I wish to once again praise Urs Schwartz’s excellent

The built-in * which* function can be used to report the file-path of m-file functions, or an indicate that the function is built-in (i.e., coded as a C/C++ function in one of the Matlab libraries):

```
>> str = which('perfTest')
str =
C:\Yair\Books\MATLAB Performance Tuning\Code\perfTest.m
>> str = which('matlab.io.MatFile')
str =
C:\Program Files\Matlab\R2013b\toolbox\matlab\iofun\+matlab\+io\MatFile.m
>> str = which('sin')
str =
built-in (C:\Program Files\Matlab\R2013b\toolbox\matlab\elfun\@double\sin)
>> str = which('noSuchFunction')
str =
''
```

Note: a little-known option enables specifying sub-functions (although this does not work for nested functions for some unknown reason [bug? oversight?]):

```
>> str = which('nestedFuncName','in','MFileName');
```

Similar functionality can be achieved via the built-in * functions*, using function handles rather than function names:

```
>> functions(@perfTest)
ans =
function: 'perfTest'
type: 'simple'
file: 'C:\Yair\Books\MATLAB Performance Tuning\Code\perfTest.m'
>> functions(@matfile)
ans =
function: 'matfile'
type: 'simple'
file: 'C:\Program Files\Matlab\R2013b\toolbox\matlab\iofun\matfile.m'
>> fType = functions(@(a)a+1)
fType =
function: '@(a)a+1'
type: 'anonymous'
file: ''
workspace: {[1x1 struct]}
>> functions(@transpose)
ans =
function: 'transpose'
type: 'simple'
file: ''
```

Unlike * which*,

```
% The following was called within the confines of a specific m-file function:
K>> fType = functions(@MFileName)
fType =
function: 'MFileName'
type: 'simple'
file: 'C:\Yair\MFileName.m'
K>> fType = functions(@subFunc)
fType =
function: 'subFunc'
type: 'scopedfunction'
file: 'C:\Yair\MFileName.m'
parentage: {'subFunc' 'MFileName'}
K>> fType = functions(@nestedFunc)
fType =
function: 'MFileName/nestedFunc'
type: 'nested'
file: 'C:\Yair\MFileName.m'
workspace: {[1x1 struct]}
```

Note that `parentage`

and `workspace`

are undocumented sub-fields of the returned struct: they are mentioned in the official doc page ^{[12]}, but only in passing, without a format explanation. Also note that `workspace`

is a cell array of a single element (contrary to the official doc – this is probably an internal bug), containing the actual workspace as a struct (fields = workspace variables). So it should be accessed as `fType.workspace{1}.varName`

. Note that `parentage`

and `workspace`

are present only for certain types of function types.

Have you found any other nifty ways of retrieving function meta-info in run-time? Are you using such meta-info in an interesting manner? If so, please post a short comment below.

Categories: Medium risk of breaking in future versions, Semi-documented function, Stock Matlab function

6 Comments (Open | Close)

Article printed from Undocumented Matlab: **https://undocumentedmatlab.com**

URL to article: **https://undocumentedmatlab.com/articles/function-definition-meta-info**

URLs in this post:

[1] posted an article: **http://blogs.mathworks.com/loren/2013/08/26/what-kind-of-matlab-file-is-this/**

[2] * mtree*:

[3] * getcallinfo*:

[4] * mlint*:

[5] * which*:

[6] * functions*:

[7] commented: **http://blogs.mathworks.com/loren/2013/08/26/what-kind-of-matlab-file-is-this/#comment-38909**

[8] Steve Johnson: **http://en.wikipedia.org/wiki/Stephen_C._Johnson**

[9] mlint: **http://undocumentedmatlab.com/blog/parsing-mlint-code-analyzer-output/**

[10] * farg*:

[11] * fdep*:

[12] doc page: **http://www.mathworks.com/help/matlab/ref/functions.html**

[13] Function call timeline profiling : **https://undocumentedmatlab.com/articles/function-call-timeline-profiling**

[14] Sparse data math info : **https://undocumentedmatlab.com/articles/sparse-data-math-info**

[15] Math libraries version info & upgrade : **https://undocumentedmatlab.com/articles/math-libraries-version-info-upgrade**

[16] The javacomponent function : **https://undocumentedmatlab.com/articles/javacomponent**

[17] The hgfeval function : **https://undocumentedmatlab.com/articles/hgfeval**

[18] sprintfc – undocumented helper function : **https://undocumentedmatlab.com/articles/sprintfc-undocumented-helper-function**

Click here to print.

Copyright © Yair Altman - Undocumented Matlab. All rights reserved.

6 Comments To "Function definition meta-info"

#1 CommentByMark BrownOn September 4, 2013 @ 12:59Yair,

I just posted on The Mathworks FileExchange, a function for finding file dependencies that uses MTREE. It should show up in a day or two as File ID# 43370. I would appreciate any feedback. Thanks.

Mark Brown

#2 CommentBySome GuyOn September 5, 2013 @ 07:08I believe that this is the author of mtree():

^{[8]}#3 CommentByYair AltmanOn September 7, 2013 @ 11:11Thanks – I have independently verified this and updated the article text accordingly. I think that it’s a great loss to MathWorks and Matlab in general that Steve no longer works on Matlab.

#4 PingbackByParsing mlint (Code Analyzer) output | Undocumented MatlabOn September 7, 2013 @ 11:14[…] much more detailed information about the nature of functions can be found using the semi-documented mtree function (or rather, Matlab class: %matlabroot%/toolbox/matlab/codetools/@mtree/mtree.m). This is a huge […]

#5 CommentByAnother guyOn November 6, 2014 @ 06:24Is there any new/additional information available on the mtree function?

#6 CommentByYair AltmanOn November 6, 2014 @ 07:01Not to my knowledge, but you’re welcome to dig in the code and if you find anything useful please post a followup comment here.