Does specific .m define particular function?

1 view (last 30 days)
When I wrote programs to analyze programs, sometimes I need to know whether a specific .m defines a particular function. What are some of the options for checking that -- preferably without having to parse the code for not-quoted not-commented not-block-commented occurrences of "function" ?
My most immediate use is in checking the properties of callbacks defined in objects to see whether they attempt to refer to undefined routines (which is unfortunately common.) By examining the properties (and possibly pulling apart function handles) I may have a string that is a function name and contextually I may have a good idea of which .m is most likely to define the function, but I need to cross-check automatically.
For greater certainty: this is not the case where the function to be looked for has its own .m file: this is the case where a .m file may define multiple functions, and so when executing within the .m the function name may resolve perfectly well, but I need to peak inside the .m to check.
Ideally the code resolution would handle arbitrarily nested functions, but for my immediate needs, simple top-level definitions would do. Some day I may need to think about extending this to classes, but not yet.
Alternately, it would be useful if there were a routine that could be given .m name and a target function name and the routine returned where the target function name would resolve to if executed within that .m . Better yet if the syntax allowed designating particular functions or scopes to start the resolution within.
I know that there must be some built-in functionality along these lines, as hgload() to restore .fig is known to do resolution of function handles at the time of the load, at least in some instances.
My existing code already analyzes function handles. Depending on how the function handle is created, sometimes the context of which filename is already available by using functions(), which makes things easy. But not all methods of creating function handles have non-empty "file" properties. :(

Accepted Answer

Walter Roberson
Walter Roberson on 17 Apr 2016
Ah, I just realized there is a way!
contains_function = @(filename, functionname) ~isempty( which([filename '>' functionname]) );
The filename can be fully qualified complete with directory and with '.m' . This does not just check to see if the file exists, it checks to see if the function exists in the file.
It will not, of course, detect functions that are dynamically created. It also cannot locate nested functions.
If you prefer to stick to documented syntax,
contains_function = @(filename, functionname) ~isempty( which(functionname, 'in', filename) );
  2 Comments
Walter Roberson
Walter Roberson on 7 Nov 2016
It turns out that "which in" does not tell you whether a function is defined in the given file: it tells you how the given file would resolve the function. If the given file happens to define the function then the function will be detected as a local function. If the given file does not happen to define the function then the function will be resolved through normal processing -- looking on the path, looking for mex, Java, and so on.
You can check many of the possibilities ahead of time using exist(), but exist() cannot resolve java and which() does resolve Java. For example,
which add in YourFile
will probably return
add is a Java method % java.util.ArrayList method
This leads having to check whether the output includes '% Local function'
Walter Roberson
Walter Roberson on 1 Dec 2016
I checked with Support and there is no function available to make this kind of check directly, so you do need to parse the output of which()

Sign in to comment.

More Answers (1)

Arnab Sen
Arnab Sen on 23 Feb 2016
Hi Walter,
The inbuilt function 'exist' can help you in this regards. It returns various code based on entity present as the given name in MATLAB path.
For more details about 'exist', refer to the following link:
  1 Comment
Walter Roberson
Walter Roberson on 17 Apr 2016
Edited: Walter Roberson on 17 Apr 2016
exist() cannot reach into a .m file to say whether the .m file defines a particular function other than the one that matches the file name. When I am running my analyzer, I am not running the file being analyzed: I am running a program that is examining a file.
For example, MyGUI.m might contain
function MyGUI
function MyGUI_edit1_Callback
function MyGUI_edit2_Callback
Now from outside, from my analyzer program, how could I ask "Does MyGUI.m contain function MyGUI_edit2_Callback ?" "Does MyGUI.m contain function MyGUI_push1_Callback" ?
You cannot put an entire .m file onto your path for the purpose of exist() . If you are not executing within the .m file then you cannot ask about the functions in the file with exist()

Sign in to comment.

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!