## Loren on the Art of MATLABTurn ideas into MATLAB

### This is machine translation

Translated by
Mouseover text to see original. Click the button below to return to the Original version of the page.

# What Kind of MATLAB File is This?15

Posted by Loren Shure,

We just had an interesting thread at MathWorks prompted by a customer request to programmatically distinguish between script and function MATLAB files. The File Browser already shows these separately. I will show some ideas we had and what we agreed was a good way to attack this.

### Contents

#### Function Vs. Script: The First Idea

The first idea was to create a function, perhaps called isfunction, and might be implemented by opening and reading the file, and looking for a function signature. Of course, you'd need to be sure that the function signature was not embedded in a comment. The tedium of doing this struck me and led me to ...

#### Function Vs. Script: The Next Idea

The next thing I thought of was to see what the function nargin did with various files on my path. I encourage you to read the documentation for this function. It's not very long.

Let's first see what happens for a "typical" function.

maxInputs = nargin('fftshift')

maxInputs =
2


We see that nargin finds that fftshift is called with up to 2 inputs.

Now let's try a function that can have any number of inputs.

maxInputs = nargin('ndgrid')

maxInputs =
-1


Here, the negative value indicates that you can input a variable number of inputs, and the first formal input is varargin.

If I were to try a script, e.g., this one, here's what I would type

    nargin('whatIsThis')

And here's the output from the command window.

  Error using nargin
whatIsThis is a script.
Error in whatIsThis (line 31)
nargin('whatIsThis')

We get an error message for this case. If we want to write a program to determine the file type, we can't have the program error out. So, in order to robustly check to see if the file is a function, we need to plan for scripts. For that, I recommend using the try/catch construct.

try
maxInputs = nargin('whatIsThis')
catch exception
if strcmp(exception.identifier, 'MATLAB:nargin:isScript')
disp('This file is a script.')
else
% We are only looking for scripts and functions so anything else
% will be reported as an error.
disp(exception.message)
end
end

This file is a script.

try
maxInputs = nargin('blogTopics.doc')
catch exception
if strcmp(exception.identifier, 'MATLAB:nargin:isScript')
disp('This file is a script.')
else
% We are only looking for scripts and functions so anything else
% will be reported as an error.
disp(exception.message)
end
end

Not a valid MATLAB file.


So now we can identify scripts without causing an error.

There's another kind of code file in MATLAB, pertaining to classes (the updated style, since R2008a, where classes are defined with (https://www.mathworks.com/help/matlab/ref/classdef.html classdef>), and we haven't done anything special to see if the file in question is for a class. I will demonstrate with the class dataset from Statistics Toolbox.

maxInputs = nargin('dataset')

maxInputs =
-1


The fact that dataset can take a variable number of inputs doesn't tell us that dataset is a class file. To probe for that information, we can use the function exist. Looking at the help, we see that if the file in question is a class file, then exist returns the value 8. To ask specifically if it's a class, we use this code.

classy = exist('dataset','class')

classy =
8


To be sure the files we probed originally are not class files, we need to check them out as well.

classy = exist('fftshift','class')

classy =
0

classy = exist('ndgrid','class')

classy =
0

classy = exist('whatIsThis','class')

classy =
0


#### Do You Need to Distinguish File Types in Your Work?

Do you have a similar need, where you need to characterize different file types, not based on their extension (e.g., .m)? I'd love to hear about cases where you need similar functionality. Let me know here.

Get the MATLAB code

Published with MATLAB® R2013a

### Note

A slightly related topic is finding the name of the currently executing mfile. I've used this a lot for ensuring that an automatic copy of a script can be saved every time it is run, along with the results it produces. This is useful when the file controls a measurement or simulation, and one wants a record of all the parameters and control flow, in case of later suspected problems. The mfilename command comes in useful: myname = [ mfilename('fullpath'), '.m' ]; The use of nargin to analyse a function file (instead of using it only within a function) was new to me. I don't remember offhand having a need, but I'll try to remember it. Finding what a file actually is (regardless of name) is important when recovering corrupted filesystem data. unix(['file ', filename]) The GNU "file" command is pretty good on its heuristics and detail. Perhaps Matlab could implement a "file" or "filetype" or "aboutfile" command, that would at least give details about all matlab recogniseable files (e.g. m-file script or function, number of arguments, mex file, hdf5-based figure, v5 mat-file etc etc) and preferably others too (text:ascii, text:utf8, pdf, etc). 
 Alfonso replied on August 27th, 2013 2:26 am UTC : 2 of 15 That was very interesting. One minor question: if I am correct, the function 'exist' only checks for classes that are on the current path, but it can not be used in conjunction with a fullpath (e.g. exist('./myfile.m','class') returns 0 even if myfile is a class definition file; similarly exist('./myfile.m') returns a 2 even if myfile is a class definition file). This, of course, creates some issues when trying to identify class definition files if one needs to discriminate among multiple files sharing the same name. So I am curious, is there some workaround for this? Loren Shure replied on August 27th, 2013 12:12 pm UTC : 3 of 15 Alfonso, Yes, exist only identifies classes that MATLAB can create at that time. You need the file in question to be accessible in MATLAB before it can be identified as a class. So be sure you have the right path. --Loren Loren Shure replied on August 27th, 2013 12:15 pm UTC : 4 of 15 Nathaniel, You are right that there is not one command alone that can identify the MATLAB files. A short combination of commands could be put together, as I have shown in this post, to get the information. Can you please say more about why you want one encompassing function and when/how you would use something like that? --Loren adam replied on August 27th, 2013 3:54 pm UTC : 5 of 15 I haven't had the need yet myself to test whether a file is a script or a function (I often find myself converting scripts to functions anyway to tidy keep variable scope constrained), but I recently wrote functionality testing if something is a class or function. We are trying to use the Matlab unit testing framework more and more and I have been writing some functions/scripts to wrap up some functionality to make it easier for members of our team who are unfamiliar with it. One of these functions is a 'createUnitTest( myFile )' function which I can just call with the class/function I have just written as argument and it will create a template with the various unit test setup/teardown/test fixtures and the inheritance from matlab.unittest.TestCase - i.e. the things that are easy to forget and put off team-members unfamiliar with the test framework from writing a test when they are in a hurry. This function does a number of things, determining where in the file tree top create the new file, etc, but it also creates a different template depending whether the file in question is a class or function in an attempt to make process of creating unit tests as painless as possible. This framework of 'helper' functions also makes use of what Nathaniel mentioned, using the path of the currently executing m-file to recursively build up test suites and similar functionality. Mark Brown replied on August 27th, 2013 4:31 pm UTC : 6 of 15 Here's a rather obscure solution using some functions that still ship with Matlab (as of R2013a). tree = mtree('classfile.m','-file'); tree.select(1).kind will return the character string: ans = CLASSDEF tree = mtree('functionfile.m','-file'); tree.select(1).kind will return the character string: ans = FUNCTION tree = mtree('scriptfile.m','-file'); tree.select(1).kind will return the character string: ans = EXPR or some other string (other than FUNCTION or CLASSDEF). MTREE is a great function that I use to parse m-files to look for file dependencies. It's fast and works much better than any other utility out there. I hope TMW doesn't deprecate it. Experiment with it! Loren Shure replied on August 27th, 2013 5:51 pm UTC : 7 of 15 Thanks, Mark. For the benefit of others, mtree is not a documented MATLAB function. Just be aware of that if you depend on it. --Loren Mario Lietz replied on August 28th, 2013 1:09 pm UTC : 8 of 15 My last function I committed to matlab fileexchange also distinguishes between script, function and class files. I simply count the number of functions that are defined within the file. I can do so, because I need all functions anyway. This is a little tricky, but with a search for regular expressions quiet fast. Therefore I compare all beginning of lines with the string „function“ txt_new = strtrim(txt); function_pos = strncmp(txt_new,'function ',9); Furhtermore, one must look for every function_pos if it is really a function with: txt = txt(10:end); funName = strtrim(regexprep(txt,'\(.*.*|\%.*','','once')); funName = regexp(name,'((\w)*\.)?(\w)*$','once','match'); If the file contains no function, it's a script file. Otherwise it’s a function or class file. To distinguish between these latter two I used the function: exist(filename,'class') . Why I look for the function names you can see here: https://www.mathworks.com/matlabcentral/fileexchange/43198-embeddedmethodsviewer-show-functions-and-methods-within-matlab-editor Loren Shure replied on August 28th, 2013 1:32 pm UTC : 9 of 15 Adam- Thanks for explaining your workflow. Mario- Thanks for sharing your algorithm. --Loren Jim Hokanson replied on August 28th, 2013 2:28 pm UTC : 10 of 15 Mark, Have you posted your parsing solution somewhere that I could look at it? If not would you be willing to send it to me? gmail: jim.hokanson Thanks, Jim Yair Altman replied on August 28th, 2013 10:06 pm UTC : 11 of 15 @Jim - Mark's comment refers to an internal m-file function (or rather, a class) that is included in Matlab releases and exists on the path (%matlabroot%\toolbox\matlab\codetools\@mtree\mtree.m). As Loren noted, this is not a supported function, and so it might go away in a future release. But as of today we can still enjoy this wonderfully complex class (3K+ lines). The file is heavily documented internally, and you're welcome to look at it. I plan to write a post about it some day. - Yair Jim Hokanson replied on August 30th, 2013 10:27 pm UTC : 12 of 15 @Yair, Thanks. Just to clarify, I actually was hoping to get the code Mark used to look for file dependencies. Unless I am missing something in mtree I am guessing it isn't much better than fdep. Unfortunately fdep has some bugs. I'm working on rewriting it using much more explicitly defined mlintmex calls than Urs used, but I always welcome someone else's solution to the problem. Jim Amro replied on September 4th, 2013 4:01 am UTC : 13 of 15 This came up on Stack Overflow a few months ago: http://stackoverflow.com/questions/15910210/distinguish-between-scripts-and-functions-programmatically All three solutions mentioned above were suggested: - manually search file content for a function signature - use nargin - use mtree to build parse tree Even though |mtree| is undocumented, it is the same function being used on Cody to score solutions. It was also used in the MATLAB online contest. Mark Brown replied on September 4th, 2013 7:55 pm UTC : 14 of 15 In response to a request by John Hokanson, I have posted my routine for finding file dependencies on The FileExchange. It should be available in a few days. Jamie replied on October 3rd, 2013 3:38 pm UTC : 15 of 15 I have an application where I am trying to determine all the functions associated with my MATLAB installation. I use the list for syntax highlighting in a text editor. With my upgrade to R2013a I found that my approach was picking up scripts so I did some poking around and was pointed to this post. I was interested to see the differences between the approach proposed here by Loren, the mtree approach, and stackoverflow solution (http://stackoverflow.com/questions/15910210/distinguish-between-scripts-and-functions-programmatically). So I applied each to a special case, mcc. It has an m-file but is linked to a mex file. Loren's approach: "mcc does not know how to answer nargin/nargout" mtree approach: "mtree (complete: 0 nodes)" stackoverflow approach: "ans = 0" (input is a function) Loren's and stackoverflow approaches give similar results but the latter picks up a few more functions like mcc, dataread, etc. that I would like to pick up for my application.         Trial software    $('.thumbnail.thumbnail_asset.asset_overlay.video a p').remove(); Select a Web Site Choose a web site to get translated content where available and see local events and offers. You can also select a web site from the following list: Americas América Latina (Español) Canada (English) United States (English) Europe Belgium (English) Denmark (English) Deutschland (Deutsch) España (Español) Finland (English) France (Français) Ireland (English) Italia (Italiano) Luxembourg (English) Netherlands (English) Norway (English) Österreich (Deutsch) Portugal (English) Sweden (English) Switzerland Deutsch English Français United Kingdom (English) Asia Pacific Australia (English) India (English) New Zealand (English) 中国 简体中文 English 日本 (日本語) 한국 (한국어) Contact your local office Explore Products MATLAB Simulink Student Software Hardware Support File Exchange Try or Buy Downloads Trial Software Contact Sales Pricing and Licensing How to Buy Learn to Use Documentation Tutorials Examples Videos and Webinars Training Get Support Installation Help Answers Consulting License Center About MathWorks Careers Newsroom Social Mission Contact Us About MathWorks MathWorks Accelerating the pace of engineering and science MathWorks is the leading developer of mathematical computing software for engineers and scientists. Discover… United States Patents Trademarks Privacy Policy Preventing Piracy Application Status © 1994-2019 The MathWorks, Inc. Join the conversation try { _satellite.pageBottom(); } catch (e) { //something went wrong } $(document).ready(function ($) { // delegate calls to data-toggle="lightbox" $(document).delegate('*[data-toggle="lightbox"]', 'click', function(event) { event.preventDefault(); return$(this).ekkoLightbox({ onShown: function() { if ($('.ekko-lightbox-container iframe').length) {$(".ekko-lightbox-container iframe").attr("scrolling","no"); $(".ekko-lightbox-container iframe").load(lightboxIframeHeight); } }, onNavigate: function(direction, itemIndex) { if (window.console) { return console.log('Navigating '+direction+'. Current item: '+itemIndex); } } }); }); // resize$(window).resize(lightboxIframeHeight) // lightbox height function function lightboxIframeHeight() { if ($('.ekko-lightbox-container iframe').length) { whichIframeHeight =$('.ekko-lightbox-container iframe').contents().find('body').height() + 20; $(".ekko-lightbox-container iframe").css("height",whichIframeHeight); } } //Programatically call$('#open-image').click(function (e) { e.preventDefault(); $(this).ekkoLightbox(); });$('#open-youtube').click(function (e) { e.preventDefault(); \$(this).ekkoLightbox(); }); });