Changing property attributes in a value class
12 views (last 30 days)
Show older comments
Is there a way to change the attributes of a class without using dynamicprops? I would like to be able to hide and reveal properties based on how objects are being used. The properties would all be defined in the class definition, but I can't find a way to change the attributes after the object is created.
2 Comments
Accepted Answer
Cedric
on 13 May 2013
Edited: Cedric
on 13 May 2013
I don't think that this "hide and reveal" approach is sound/wise. You can implement whatever logic in your methods so they work differently depending on the context, but what do you mean by "hiding methods/properties"? Could you not just avoid using them when not relevant? Very few end users really use class/object introspection mechanisms actually, and in my opinion it would be a mistake to try hiding anything to those who do. Actually, as a user, I much prefer having a clean object/class that triggers an error() when I am using one of its methods inappropriately, than a class that tricks introspection mechanisms.
I don't think that you can dynamically make private properties/methods public and vice versa. If you really want to manage hiding properties/methods, the only trick that I can think of is to overload METHODS, FIELDNAMES, and PROPERTIES. I don't think that it would be wise to overload METACLASS, because you would not be able to reproduce easily its output.
2 Comments
Cedric
on 13 May 2013
Edited: Cedric
on 13 May 2013
You can always create a class A that, when instantiated, creates an object of class B or C depending the context and stores it as a property. Then you can either create getters and setters that will manage accesses to properties of B or C appropriately (not my favorite solution), or overload SUBSASGN, SUBSREF, SUBSINDEX, METHODS, PROPERTIES, FIELDNAMES, METACLASS, and a few others like NUMEL, LENGTH, SIZE, CLASS, END, DISP, etc. This could be a valid approach if implemented well, which would require work but wouldn't be out of reach.
The difference between this and what I qualified as not being sound/wise in my first comment is the following: if you have to overload METACLASS and generate its output from scratch, you can be almost certain that it is not going to work, because of the complexity of the output of METACLASS; if, however, you have instantiated some other class and saved it as a property, your overload just needs to output the built-in METACLASS applied to the property, e.g.
...
properties
subObj
end
...
methods
function self = A(type, varargin) % Constructor.
switch type
case ...
self.subObj = B(varargin{:}) ;
case ...
self.subObj = C(varargin{:}) ;
else
error('Huh?') ;
end
function varargout = metaclass(self, varargin) % Overload.
varargout = metaclass(self.subObj, varargin{:}) ;
end
function varargout = methods(self, varargin) ... end
function varargout = properties(self, varargin) ... end
function names = fieldnames(self, varargin) ... end
function self = subsasgn(self, S, value) ... end
function ind = subsindex(self) ... end
function varargout = subsref(self, S) ... end
function s = size(self, varargin) ... end
function n = numel(self, varargin) ... end
function l = length(self, varargin) ... end
function out = end(self, k, ~) ... end
function disp(self, varargin) ... end
function flag = iscolumn(self, varargin) ... end
function flag = isfloat(self, varargin) ... end
.. etc
end
I guess that the part that would require the more work would be SUBSASGN and SUBSREF (~ 1 day of work including full testing for me), that have to "transfer" indexing (including methods call) on self.subObj.
Building this would certainly be a nice training to OOP in MATLAB, but I would keep that as a side/experimental project for a while, and definitely build a lengthy and exhaustive test script.
More Answers (0)
See Also
Categories
Find more on Class Introspection and Metadata in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!