**- 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 ^{[3]} 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**^{[4]}**getcallinfo**^{[5]}**mlint**^{[6]}**which**^{[7]}**functions**^{[8]}

Reader Mark Brown has commented ^{[9]} 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, * mtree* includes no personal credit although it appears to be very well written and documented. I have to congratulate the unknown author(s) for both their proficiency and humility.

For people worried about future compatibility, note that * mtree* has existed on the Matlab path (%matlabroot%\toolbox\matlab\codetools\@mtree\mtree.m) since 2006 (I think R2006a, but I’m not certain; it already had version 1.3 by R2007b; the latest version [R2013b] is 2.5). Considering the large investment in its code thus far, and the significant effort that it would take to create a replacement, I don’t see this function going away in the near future. Then again, there is no certainty about this, and it might well disappear without notice in some future Matlab release.

* 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 ^{[11]} 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 **farg**^{[12]} and **fdep**^{[13]} utilities, which use this undocumented * mlint* syntax. They seem to out-perform and out-class the built-in

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 ^{[14]}, 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/blog/function-definition-meta-info**

URLs in this post:

[1] Image: **http://undocumentedmatlab.com/feed/**

[2] **email feed**: **http://undocumentedmatlab.com/subscribe_email.html**

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

[4] * mtree*:

[5] * getcallinfo*:

[6] * mlint*:

[7] * which*:

[8] * functions*:

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

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

[11] mlint: **https://undocumentedmatlab.com/blog/parsing-mlint-code-analyzer-output/**

[12] * farg*:

[13] * fdep*:

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

[15] Customizing print setup : **https://undocumentedmatlab.com/blog/customizing-print-setup**

[16] Context-Sensitive Help : **https://undocumentedmatlab.com/blog/context-sensitive-help**

[17] Matlab DDE support : **https://undocumentedmatlab.com/blog/matlab-dde-support**

[18] handle2struct, struct2handle & Matlab 8.0 : **https://undocumentedmatlab.com/blog/handle2struct-struct2handle-and-matlab-8**

[19] Types of undocumented Matlab aspects : **https://undocumentedmatlab.com/blog/types-of-undocumented-matlab-aspects**

[20] Handle Graphics Behavior : **https://undocumentedmatlab.com/blog/handle-graphics-behavior**

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:59 pmYair,

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 @ 7:08 amI believe that this is the author of mtree():

^{[10]}#3 CommentByYair AltmanOn September 7, 2013 @ 11:11 amThanks – 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 am[…] 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 @ 6:24 amIs there any new/additional information available on the mtree function?

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