3

I have observed a strange behavior in running the same code in a Matlab function and in the command window. It's already described in How does scoping in Matlab work? , but I don't understand how I could solve my specific problem. The code is the following:

exporteddata.m  %File created by an external program 
                %to export data in Matlab format

surface = struct('vertices', [...]) ; 
                         %I can't specify in the external program 
                         %the name of the variable, it's always "surface"

My actual code is:

   myfunction.m 

   function output = myfunction(input)
   load(input);
   n = size(surface.vertices);
  ....

When running

myfunction('exporteddata.m'); 

I get the following error:

??? No appropriate method, property, or field vertices for class hg.surface.

When running the same instructions from the command window or in debug mode, the code works well.

How can I specify in the function that I need the variable surface present in the workspace, not the Matlab function?

Community
  • 1
  • 1
lib
  • 2,918
  • 3
  • 27
  • 53

1 Answers1

3

First of all, I must point out that surface is a built-in function in MATLAB, so overloading it is just... bad. Bad, bad, BAD!

Having said that, the MATLAB interpreter does a pretty good job at resolving variable names and usually tells them apart from function names correctly. So where's your problem, you ask?
I believe that you're using the wrong function: load is a function that loads data from MAT files into the workspace. It is not fit for m-files. By not executing "exportedata.m" properly, surface has never been created as a variable, so MATLAB identifies it as a function name. If you want to execute "exportedata.m", just type:

exportedata

and if you want to run the file with the filename stored in input, you can use run:

run(input)

By executing run(input) from within myfunction, surface should be created in myfunction's local scope, and it should work.

EDIT:
I've just tested it, and the interpreter still gets confused. so the issue of the variable name resolution remains. Here's a workaround:

function output = myfunction(input)
   surface = 0;                     %// <-- Pay attention to this line
   run(input);
   n = size(surface.vertices);

Predefining surface allows the interpreter to identify it as a variable throughout your entire function. I've tried it and it works.

Eitan T
  • 32,660
  • 14
  • 72
  • 109
  • The problem is that the variable surface does not exist before run(input), so I can't pass it as an argument to the function! – lib Jan 28 '13 at 11:31
  • The only alternative which comes to my mind is to open exporteddata,m as a text file and replace "surface" with "myVar". But I'm interested to exploit Matlab scoping mechanism, if that is possible – lib Jan 28 '13 at 11:33
  • Ok, then can you add more details (in your question) about how you run `exportedata.m` and `myfunction.m`? Is `myfunction` invoked from an external script that also calls `exportedata`? – Eitan T Jan 28 '13 at 11:35
  • sorry, I'm going to edit it. anyway, input= exporteddata.m ; myfunction(input); – lib Jan 28 '13 at 11:37
  • 1
    Yes, now it works! Thank you! You saved me from messying my code and implementing a search/replace function! – lib Jan 28 '13 at 12:53
  • Just to be a little pedantic - `surface` is a function that ships with MATLAB, not a keyword (like `if`, `else` etc.). MATLAB also has very clear rules about precedence of variables, functions, methods etc. http://www.mathworks.com/help/matlab/matlab_prog/function-precedence-order.html – Edric Jan 28 '13 at 12:57
  • @Edric Thank you for your comment. This is what I meant, but I'll revise the wording to clarify that. Regarding the precedence, however, I thought MATLAB would've checked for the `surface` variable in `myfunction`'s scope before assuming it's a function, but it doesn't do so... – Eitan T Jan 28 '13 at 13:05
  • For the precedence issue, you can find an explanation in the first answer of my link: "MATLAB parses the function before it's ever run. It looks for variable names, for instance, regardless of the branching that activates (or doesn't activate) those variables"... Anyway I didn't realize what I should have done to avoid my problem! – lib Jan 28 '13 at 13:11