function obj=testMe()
obj.a=4;
obj.getA = @getA;
obj.setA = @setA;
function val=getA()
val=obj.a;
end
function setA(val)
obj.a=val;
end
end
And here are the results:
>> a=testMe;
>> a.getA()
ans =
4
>> a.setA(10);
>> a.a
ans =
4
>> a.getA()
ans =
10
Why are the two values different? Where is the second variable stored?
I am not too familiar with Matlab and I have 400 lines of tight code with complex logic written in a similar way with nested classes, etc. I badly need to resolve this issue. Can somebody help?
Each internal nested function saves its workspace as part of the function
handle and that is the workspace it uses. Execute
functions(a.getA)
to explore it. In other words, getA and setA are not operating on the
variable you think they are.
As such, you don't need to include a as a member of your struct at all.
This will do the same thing and you won't be tempted to try getting the
internal_value by any means other than getA because it's obviously not in
the "object".
-------------------------------
function obj = objtest()
internal_value = 4;
obj.getA = @getA;
obj.setA = @setA;
function val = getA()
val = internal_value;
end
function setA(val)
internal_value = val;
end
end
--------------------------------
And now we run it:
>> b=objtest;
>> b.getA()
ans =
4
>> b.setA(10)
>> b.getA()
ans =
10
I hope this helps.
--
Doug Schwarz
dmschwarz&ieee,org
Make obvious changes to get real email address.
Thanks for this perfect example for NOT using nested functions!
Regards
Markus
I want to comment on this conclusion since I
think "closures" (http://en.wikipedia.org/wiki/Closure_%
28computer_science%29, 2007-09-01) realized with function
handles and nested functions is the best feature added to
Matlab since "function". It's actually better than sliced
bread.
The original post in this thread reads:
Jason Ingram 2007-04-24 wrote:
function val=getA()
val=obj.a;
end
>> a=testMe;
>> a.getA()
ans =
4
>> a.getA()
ans =
10
<end original post>
The short answere is: It is a mistake to (try to) make the
variable "a" public as part of the structure (i.e. as a.a).
myobj = testMe()
creates a structure, which obeys the Matlab rules of copy-
by-value. The values of two fields of the structure, myobj,
are function handles of nested functions, which in turn
share a scope(/workspace). These function handles contain
*references* to variables in the main function, testMe. The
function handles are references, i.e. a copy of a function
handle refers to the same underlying "stuff". The details
on the scope are in the documentation.
The assignment
myobj.a = 10;
"triggers" the copy-by-value-rules and makes myobj.a refer
to another piece of memory and thus the connection with
obj.a in testMe is broken.
The conclusion is that access to the state of the object
must be done with the help of function handles to nested
functions.
These "closures" are a bit frustrating. They allow us to do
a bit of object oriented stuff, but just a bit and we have
to find out about the limitaions ourself. BTW, I couldn't
see any sign of Matlabs new class-system in the release
note of R2007b.
Reading:
1. <Loren on the Art of MATLAB>, August 9th, 2007, A Way to
Create Reusable Tools, specially the comment by
Michael Corvin replied on August 16th, 2007 at 11:28 pm :
There is more to find i Lorens blogs, but it takes some
time to find it.
2. cssm (this newsgroup), thread: THIS (or SELF) object in
matlab, 2005-11-23. Tom Krauss proposes a clever construct
that allows us to write: myobf.a = 10;
A quick fix to testMe would be:
function obj=testMe()
obj.getA = @getA;
obj.setA = @setA;
state.a = 4;
function val=getA()
val=state.a;
end
function setA(val)
state.a=val;
end
end
There are undocumented stuff in Matlab (e.g. schema,
handle) that make it possible to take this further. See the
code of memmapfile. But that's for experts.
/ per