How can you create local variables from class properties?

Is there a way to automatically create local variables corresponding to a class' properties?
Lets say I have a class instance foo, with properties A, B, C. I want to create local variables A, B, and C that are copies of foo.A, foo.B, and foo.C.
foo = fooclass;
A=foo.A;
B=foo.B;
C=foo.C;
Obviously, one could simply do the above -- however, for a case with a moderate number of parameters (and different parameters per situation), it would be nice if they could all be created in one go -- kinda like a smarter deal. For bonus points, the inverse operation would also be great. i.e.:
foo.A = A;
foo.B = B;
foo.C = C;
I can imagine writing a script that will do this in a given workspace -- but I don't see a way to make it a function that will create these variables in a calling workspace. Of course this uses eval (shudder) -- and you aren't supposed to do this -- and yes, I know my whole question is an elaborate version of creating variables with eval, which everyone should know better than. However, in this case, I think/hope it could actually result in less error prone code.
pnames = parameters(foo);
for i=1:length(pnames)
eval( [ pnames{i} ' = foo.' pnames{i} ';']);
end
I guess you could write a function that would build up a long eval string and return it, you could then just eval that...
eval( foo.abomination() );

6 Comments

Why do you want to do this? Why not just use the class properties directly?
"However, in this case, I think/hope it could actually result in less error prone code."
Would you care to explain your reasoning? It really is not obvious why you think/hope that.
What it would definitely result in: slower, more obfuscated code.
Note that I am not talking about creating a large number of such variables -- they will not be numbered or lettered in some programmatic fashion. Instead, what I want to do is much more like a save/load operation -- where the class is the storage.
I expect there to be about 5-15 of these variables in a given class. There will be different classes with different variable names. So, the manual 'load' process will be 5-15 lines of code. The matching 'save' process will be another 5-15 lines of code. As these classes are developed, parameters will be added/removed/renamed. These 5-15 lines of code will need to be maintained for every change. In my experience, this kind of code is exactly the kind of thing that people fail to maintain. It is very easy to forget an update -- or to copy/paste a line and not make all the changes for a new variable -- or to do the load, but forget the matching store...
One line that told you exactly what it was doing to replace 5-15 error prone lines seems to me like it could reduce problems in some situations.
foo = fooclass;
PoofPublicParametersIntoExistance( foo );
If I really wanted to be sadistic, I could do it with a save/load pair -- have the saving function return the name of the file...
Without elegant support, forcing use of the class members all the time will likely be the solution (foo.A, foo.B, etc). That just gets ugly when you need to pass 6-8 such parameters to another function.
Without elegant support, forcing use of the class members all the time will likely be the solution (foo.A, foo.B, etc). That just gets ugly when you need to pass 6-8 such parameters to another function.
Why not pass the object into the "another function" and let that function retrieve only the properties from the object that it requires? That way, the calling function neither knows nor cares if the function it's calling suddenly requires more information from the object to do its work.
"...forcing use of the class members all the time will likely be the solution (foo.A, foo.B, etc)"
That is exactly what I would recommend, and it seems to be the one simple solution that you are trying to avoid... Once I started doing this my own code also became easier to work with: easier to search, to follow the data flow, and identify origins of data. I see explicitly naming the class/structure/whatever as a benefit (not as a disadvantage), much like obtaining and using explicit graphics handles adds 10% work but gives a 20% benefit.
@Steven Lord -- the functions I'm calling are somewhat general purpose. Changing them to always expect their arguments as a particular class would reduce their generality.
@Stephen Cobeldick -- the object is a property in another object, so, every argument passed really turns into obj.foo.A and obj.foo.B -- for a function with a significant number of arguments, this becomes onerous. It still looks to be the answer, but it isn't pretty.

Sign in to comment.

Answers (1)

A better alternative to eval is to use my structvars FEX submission
It works on objects too. Example:
classdef myclass
properties
A
B
C
end
end
>> structvars(myclass)
A = S.A;
B = S.B;
C = S.C;

2 Comments

Thanks for bringing this to my attention. I don't think it is right for me this time, but I appreciate your ingineuity coming up with this approach.
I guess you could write a function that would build up a long eval string and return it, you could then just eval that... eval( foo.abomination() );
Note that the foo.abomination idea that you mention in your original post is exactly what structvars does.
eval(structvars(foo).')
Of course, I strongly advise against using it that way...

Sign in to comment.

Products

Release

R2019b

Asked:

on 1 Oct 2019

Commented:

on 4 Oct 2019

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!