Re: Interesting function vs. script variable scope/precedence question
- From: "Steven Lord" <slord@xxxxxxxxxxxxx>
- Date: Wed, 2 Jan 2008 17:01:03 -0500
"Doug" <logickle@xxxxxxxxx> wrote in message
news:14516617.1199308768234.JavaMail.jakarta@xxxxxxxxxxxxxxxxxxxxxxxxx
Hi, all. I'm converting a script to a function, and something which worked
before now doesn't. (ML 6.5R13, BTW)
I've saved an array named 'db' into a MAT file called FOO, and in my
function I call 'load FOO'
When my code was in a script, this caused 'db' to be loaded into the
workspace just fine - I could see 'db' in the Workspace window, Base
workspace, and I could perform operations on it, e.g. 'size(db,1)'.
Correct. Scripts execute in the workspace of their caller, and the script
is executed one line at a time.
Now that the code is in a function, the call to size() fails, with this
message to the command window:
??? Input argument 'U' is undefined.
Error in ==> C:\MATLAB6p5\toolbox\signal\signal\db.m
On line 46 ==> idx=strmatch(lower(U),{'power','voltage'});
Error in ==> C:\MATLAB6p5\work\newfunc.m
On line 47 ==> size(db,1);
So in the context of a function call, size is "seeing" the file db.m
first, rather than the local variable db.
Sort of.
This page is from the most recent documentation, but the important part
(What Happens When You Call a Function) hasn't changed between MATLAB 6.5
(R13) and the current version.
http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_prog/f7-58170.html
When you run a function, first MATLAB has to parse the function. When it
reaches the line in your code where you refer to db, it asks "Do I know that
db is a variable?" Since no line of code in your function has assigned a
value to db, the parser can't tell if db should be a variable. It next asks
"Is db a function?" Since there is a db.m function file on your path, the
parser says "That must be a call to the db function."
Now I can see in the Workspace windows that db is loaded into the
function's workspace. Even weirder, if I include the line 'whos db' in the
function, I get this in the command window:
Name Size Bytes Class
db 36832x197 58047232 double array
Grand total is 7255904 elements using 58047232 bytes
which is the description of the array 'db'!
Yes. At runtime, after you load your MAT-file, db is a variable ... but at
parse time, the parser decided that the instance of db in your code was a
function call and it can't change that at runtime.
So some functions 'see' the variable db when called from my function (e.g.
whos), as I expect them to.
But others don't (e.g. size()). The ones that don't see the variable see a
same-named .m file first, instead.
Actually, you never get to the call to SIZE in this case. Before newfunc.m
calls SIZE, it needs to evaluate the input arguments. To do that, it calls
the DB function with zero input arguments, and since DB expects at least one
input argument, the error comes from inside DB.
A simple workaround would be to just rename the db variable, I know. But
that's a hack - I'd really like to know how the precedence and/or scope
rules differ in the two cases.
In the past, I've called the behavior where you load a variable into the
workspace "poofing", and I recommend that you avoid it. There are a couple
of alternatives:
1) Rename your variable in the MAT-file. This works, but if we introduce a
new function with the new name in a future version, your code will break
again.
2) Assign a value to the variable before your LOAD call. If your code
includes the statement "db = [];" before your LOAD call, the parser will be
able to see the assignment when it parses newfunc.m and will know that db is
a variable.
3) Call LOAD with an output argument. The variables in the MAT-file will
become fields of the output structure. For instance, if you execute "S =
load('matfileContainingDb.mat')", refer to the db variable stored in the
MAT-file as S.db later in your code.
I recommend alternatives 2 or 3 if possible. There's a summary of what I
wrote in this document on the support website:
http://www.mathworks.com/support/solutions/data/1-166JL.html?solution=1-166JL
--
Steve Lord
slord@xxxxxxxxxxxxx
.
- References:
- Prev by Date: Re: import .mat with GUI
- Next by Date: Re: Interesting function vs. script variable scope/precedence question
- Previous by thread: Re: Interesting function vs. script variable scope/precedence question
- Next by thread: Interesting function vs. script variable scope/precedence question
- Index(es):
Relevant Pages
|