{"id":767,"date":"2013-08-26T09:13:24","date_gmt":"2013-08-26T14:13:24","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/?p=767"},"modified":"2013-08-23T09:15:15","modified_gmt":"2013-08-23T14:15:15","slug":"what-kind-of-matlab-file-is-this","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2013\/08\/26\/what-kind-of-matlab-file-is-this\/","title":{"rendered":"What Kind of MATLAB File is This?"},"content":{"rendered":"\r\n<div class=\"content\"><!--introduction--><p>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.<\/p><!--\/introduction--><h3>Contents<\/h3><div><ul><li><a href=\"#06c4e736-f854-4f8a-8516-ddaa51db5106\">Function Vs. Script: The First Idea<\/a><\/li><li><a href=\"#5d831cfb-8755-4345-a74d-3187d75a1733\">Function Vs. Script: The Next Idea<\/a><\/li><li><a href=\"#93567f7d-02b7-4907-965b-39edddcbf065\">What about Classes?<\/a><\/li><li><a href=\"#9de9951b-94f7-4edd-b94a-d6b207b2ccbf\">Do You Need to Distinguish File Types in Your Work?<\/a><\/li><\/ul><\/div><h4>Function Vs. Script: The First Idea<a name=\"06c4e736-f854-4f8a-8516-ddaa51db5106\"><\/a><\/h4><p>The first idea was to create a function, perhaps called <tt>isfunction<\/tt>, 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 ...<\/p><h4>Function Vs. Script: The Next Idea<a name=\"5d831cfb-8755-4345-a74d-3187d75a1733\"><\/a><\/h4><p>The next thing I thought of was to see what the function <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/nargin.html\"><tt>nargin<\/tt><\/a> did with various files on my path.  I encourage you to read the documentation for this function.  It's not very long.<\/p><p>Let's first see what happens for a \"typical\" function.<\/p><pre class=\"codeinput\">maxInputs = nargin(<span class=\"string\">'fftshift'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">maxInputs =\r\n     2\r\n<\/pre><p>We see that <tt>nargin<\/tt> finds that <tt>fftshift<\/tt> is called with up to 2 inputs.<\/p><p>Now let's try a function that can have any number of inputs.<\/p><pre class=\"codeinput\">maxInputs = nargin(<span class=\"string\">'ndgrid'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">maxInputs =\r\n    -1\r\n<\/pre><p>Here, the negative value indicates that you can input a variable number of inputs, and the first formal input is <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/varargin.html\"><tt>varargin<\/tt><\/a>.<\/p><p>If I were to try a script, e.g., this one, here's what I would type<\/p><pre>    nargin('whatIsThis')<\/pre><p>And here's the output from the command window.<\/p><pre>  Error using nargin\r\n  whatIsThis is a script.\r\n  Error in whatIsThis (line 31)\r\n  nargin('whatIsThis')<\/pre><p>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 <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/try.html\"><tt>try\/catch<\/tt><\/a> construct.<\/p><pre class=\"codeinput\"><span class=\"keyword\">try<\/span>\r\n    maxInputs = nargin(<span class=\"string\">'whatIsThis'<\/span>)\r\n<span class=\"keyword\">catch<\/span> exception\r\n    <span class=\"keyword\">if<\/span> strcmp(exception.identifier, <span class=\"string\">'MATLAB:nargin:isScript'<\/span>)\r\n        disp(<span class=\"string\">'This file is a script.'<\/span>)\r\n    <span class=\"keyword\">else<\/span>\r\n        <span class=\"comment\">% We are only looking for scripts and functions so anything else<\/span>\r\n        <span class=\"comment\">% will be reported as an error.<\/span>\r\n        disp(exception.message)\r\n    <span class=\"keyword\">end<\/span>\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><pre class=\"codeoutput\">This file is a script.\r\n<\/pre><pre class=\"codeinput\"><span class=\"keyword\">try<\/span>\r\n    maxInputs = nargin(<span class=\"string\">'blogTopics.doc'<\/span>)\r\n<span class=\"keyword\">catch<\/span> exception\r\n    <span class=\"keyword\">if<\/span> strcmp(exception.identifier, <span class=\"string\">'MATLAB:nargin:isScript'<\/span>)\r\n        disp(<span class=\"string\">'This file is a script.'<\/span>)\r\n    <span class=\"keyword\">else<\/span>\r\n        <span class=\"comment\">% We are only looking for scripts and functions so anything else<\/span>\r\n        <span class=\"comment\">% will be reported as an error.<\/span>\r\n        disp(exception.message)\r\n    <span class=\"keyword\">end<\/span>\r\n<span class=\"keyword\">end<\/span>\r\n<\/pre><pre class=\"codeoutput\">Not a valid MATLAB file.\r\n<\/pre><p>So now we can identify scripts without causing an error.<\/p><h4>What about Classes?<a name=\"93567f7d-02b7-4907-965b-39edddcbf065\"><\/a><\/h4><p>There's another kind of code file in MATLAB, pertaining to classes (the updated style, since R2008a, where classes are defined with (<a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/classdef.html\">https:\/\/www.mathworks.com\/help\/matlab\/ref\/classdef.html<\/a> <tt>classdef<\/tt>&gt;), and we haven't done anything special to see if the file in question is for a class.  I will demonstrate with the class <a href=\"https:\/\/www.mathworks.com\/help\/stats\/dataset.html\"><tt>dataset<\/tt><\/a> from Statistics Toolbox.<\/p><pre class=\"codeinput\">maxInputs = nargin(<span class=\"string\">'dataset'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">maxInputs =\r\n    -1\r\n<\/pre><p>The fact that <tt>dataset<\/tt> can take a variable number of inputs doesn't tell us that <tt>dataset<\/tt> is a class file.  To probe for that information, we can use the function <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/exist.html\"><tt>exist<\/tt><\/a>.  Looking at the help, we see that if the file in question is a class file, then <tt>exist<\/tt> returns the value 8.  To ask specifically if it's a class, we use this code.<\/p><pre class=\"codeinput\">classy = exist(<span class=\"string\">'dataset'<\/span>,<span class=\"string\">'class'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">classy =\r\n     8\r\n<\/pre><p>To be sure the files we probed originally are <b>not<\/b> class files, we need to check them out as well.<\/p><pre class=\"codeinput\">classy = exist(<span class=\"string\">'fftshift'<\/span>,<span class=\"string\">'class'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">classy =\r\n     0\r\n<\/pre><pre class=\"codeinput\">classy = exist(<span class=\"string\">'ndgrid'<\/span>,<span class=\"string\">'class'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">classy =\r\n     0\r\n<\/pre><pre class=\"codeinput\">classy = exist(<span class=\"string\">'whatIsThis'<\/span>,<span class=\"string\">'class'<\/span>)\r\n<\/pre><pre class=\"codeoutput\">classy =\r\n     0\r\n<\/pre><h4>Do You Need to Distinguish File Types in Your Work?<a name=\"9de9951b-94f7-4edd-b94a-d6b207b2ccbf\"><\/a><\/h4><p>Do you have a similar need, where you need to characterize different file types, not based on their extension (e.g., <tt>.m<\/tt>)?  I'd love to hear about cases where you need similar functionality.  Let me know <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=767#respond\">here<\/a>.<\/p><script language=\"JavaScript\"> <!-- \r\n    function grabCode_85a05550c18b4c8893a677b49d912628() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='85a05550c18b4c8893a677b49d912628 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 85a05550c18b4c8893a677b49d912628';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2013 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script><p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><br><a href=\"javascript:grabCode_85a05550c18b4c8893a677b49d912628()\"><span style=\"font-size: x-small;        font-style: italic;\">Get \r\n      the MATLAB code <noscript>(requires JavaScript)<\/noscript><\/span><\/a><br><br>\r\n      Published with MATLAB&reg; R2013a<br><\/p><p class=\"footer\"><br>\r\n      Published with MATLAB&reg; R2013a<br><\/p><\/div><!--\r\n85a05550c18b4c8893a677b49d912628 ##### SOURCE BEGIN #####\r\n%% What Kind of MATLAB File is This?\r\n% We just had an interesting thread at MathWorks prompted by a customer\r\n% request to programmatically distinguish between script and function\r\n% MATLAB files. The File Browser already shows these separately. I will\r\n% show some ideas we had and what we agreed was a good way to attack this.\r\n%% Function Vs. Script: The First Idea\r\n% The first idea was to create a function, perhaps called |isfunction|, and\r\n% might be implemented by opening and reading the file, and looking for a\r\n% function signature.  Of course, you'd need to be sure that the function\r\n% signature was not embedded in a comment.  The tedium of doing this struck\r\n% me and led me to ...\r\n%% Function Vs. Script: The Next Idea\r\n% The next thing I thought of was to see what the function\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/nargin.html |nargin|> did with\r\n% various files on my path.  I encourage you to read the documentation for\r\n% this function.  It's not very long.\r\n%%\r\n% Let's first see what happens for a \"typical\" function.\r\nmaxInputs = nargin('fftshift')\r\n%%\r\n% We see that |nargin| finds that |fftshift| is called with up to 2 inputs.\r\n%%\r\n% Now let's try a function that can have any number of inputs.\r\nmaxInputs = nargin('ndgrid')\r\n%%\r\n% Here, the negative value indicates that you can input a variable number\r\n% of inputs, and the first formal input is\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/varargin.html |varargin|>.\r\n%%\r\n% If I were to try a script, e.g., this one, here's what I would type\r\n%\r\n%      nargin('whatIsThis')\r\n%\r\n% And here's the output from the command window.\r\n%\r\n%    Error using nargin\r\n%    whatIsThis is a script.\r\n%    Error in whatIsThis (line 31)\r\n%    nargin('whatIsThis')\r\n%%\r\n% We get an error message for this case.  If we want to write a program\r\n% to determine the file type, we can't have the program error out.  So, in\r\n% order to robustly check to see if the file is a function, we need to plan\r\n% for scripts.  For that, I recommend using the\r\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/try.html |try\/catch|>\r\n% construct.\r\ntry\r\n    maxInputs = nargin('whatIsThis')\r\ncatch exception\r\n    if strcmp(exception.identifier, 'MATLAB:nargin:isScript')\r\n        disp('This file is a script.')\r\n    else\r\n        % We are only looking for scripts and functions so anything else\r\n        % will be reported as an error.\r\n        disp(exception.message)\r\n    end\r\nend\r\n%%\r\ntry\r\n    maxInputs = nargin('blogTopics.doc')\r\ncatch exception\r\n    if strcmp(exception.identifier, 'MATLAB:nargin:isScript')\r\n        disp('This file is a script.')\r\n    else\r\n        % We are only looking for scripts and functions so anything else\r\n        % will be reported as an error.\r\n        disp(exception.message)\r\n    end\r\nend\r\n%%\r\n% So now we can identify scripts without causing an error.\r\n%% What about Classes?\r\n% There's another kind of code file in MATLAB, pertaining to classes (the\r\n% updated style, since R2008a, where classes are defined with\r\n% (https:\/\/www.mathworks.com\/help\/matlab\/ref\/classdef.html |classdef|>), and\r\n% we haven't done anything special to see if the file in question is for a\r\n% class.  I will demonstrate with the class\r\n% <https:\/\/www.mathworks.com\/help\/stats\/dataset.html |dataset|> from\r\n% Statistics Toolbox.\r\nmaxInputs = nargin('dataset')\r\n%%\r\n% The fact that |dataset| can take a variable number of inputs doesn't tell\r\n% us that |dataset| is a class file.  To probe for that information, we can\r\n% use the function <https:\/\/www.mathworks.com\/help\/matlab\/ref\/exist.html\r\n% |exist|>.  Looking at the help, we see that if the file in question is a\r\n% class file, then |exist| returns the value 8.  To ask specifically if\r\n% it's a class, we use this code.\r\nclassy = exist('dataset','class')\r\n%%\r\n% To be sure the files we probed originally are *not* class files, we need\r\n% to check them out as well.\r\nclassy = exist('fftshift','class')\r\n%%\r\nclassy = exist('ndgrid','class')\r\n%%\r\nclassy = exist('whatIsThis','class')\r\n%% Do You Need to Distinguish File Types in Your Work?\r\n% Do you have a similar need, where you need to characterize different file\r\n% types, not based on their extension (e.g., |.m|)?  I'd love to hear about\r\n% cases where you need similar functionality.  Let me know\r\n% <https:\/\/blogs.mathworks.com\/loren\/?p=767#respond here>.\r\n\r\n##### SOURCE END ##### 85a05550c18b4c8893a677b49d912628\r\n-->","protected":false},"excerpt":{"rendered":"<!--introduction--><p>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.... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2013\/08\/26\/what-kind-of-matlab-file-is-this\/\">read more >><\/a><\/p>","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[39,13],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/767"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=767"}],"version-history":[{"count":6,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/767\/revisions"}],"predecessor-version":[{"id":774,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/767\/revisions\/774"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=767"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=767"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=767"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}