How can you create local variables from class properties?

13 vues (au cours des 30 derniers jours)
Rob McDonald
Rob McDonald le 1 Oct 2019
Commenté : Matt J le 4 Oct 2019
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 commentaires
Stephen23
Stephen23 le 2 Oct 2019
Modifié(e) : Stephen23 le 2 Oct 2019
"...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.
Rob McDonald
Rob McDonald le 4 Oct 2019
@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.

Connectez-vous pour commenter.

Réponses (1)

Matt J
Matt J le 1 Oct 2019
Modifié(e) : Matt J le 1 Oct 2019
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 commentaires
Rob McDonald
Rob McDonald le 4 Oct 2019
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.
Matt J
Matt J le 4 Oct 2019
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...

Connectez-vous pour commenter.

Produits


Version

R2019b

Community Treasure Hunt

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

Start Hunting!

Translated by