OOP Dynamic Properties ordering is very strange...
Ältere Kommentare anzeigen
I have a class defintion which makes use of OOP dynamicprops and I've noticed some odd behaivor in accessing the properties.
classdef myClass < dynamicprops
properties
x
end
methods
function this = myClass(x)
this.x = x;
end
end
end
If I add new properties to the class in a script which looks something like this
clear all
clear classes
hObj = myClass(10);
hObj.addprop('a');
hObj.addprop('b');
hObj.addprop('c');
hObj.addprop('d');
hObj.addprop('e');
fn = fieldnames(hObj)'
I was expecting the properties to be added to hObj in the same order that they are scripted in, but I find that the properties added to hObj do not get added in any consistent way. EVERY TIME I run the script, hObj is returned with a different order in the properties ?! Can anyone explain why these dynamic properties behave in such a stranage way? Is there no way to control the order in which these properties appear in the object?
It would be nice if I could control the order so that a function call like fieldnames(hObj) would return values in a predictable way. As a secondary but also irksome issue there appears to be no way to REMOVE a dynamic property once it has been added?!
... here is the output from 5 runs of the script I show above in R2010b:
fn =
'x' 'b' 'a' 'c' 'd' 'e'
fn =
'x' 'd' 'e' 'a' 'c' 'b'
fn =
'x' 'd' 'a' 'b' 'e' 'c'
fn =
'x' 'b' 'd' 'a' 'c' 'e'
fn =
'x' 'b' 'a' 'd' 'c' 'e'
Akzeptierte Antwort
Weitere Antworten (4)
William Warriner
am 5 Aug. 2019
Bearbeitet: William Warriner
am 10 Mär. 2020
I know this is a tremendously old question, but thought I would add that in (at latest) R2018b one can do the following, and it seems to work. Hopefully this helps future solution seekers like myself.
Add public overrides for properties and fieldnames like below. Technically properties() isn't a method of handle dynamicprops, but this should still work because methods are called before built-ins (https://www.mathworks.com/help/matlab/matlab_prog/function-precedence-order.html).
function value = properties( obj )
if nargout == 0
disp( builtin( "properties", obj ) );
else
value = sort( builtin( "properties", obj ) );
end
end
function value = fieldnames( obj )
value = sort( builtin( "fieldnames", obj ) );
end
Add a matlab.mixin.CustomDisplay superclass and add protected override like below.
function group = getPropertyGroups( obj )
props = properties( obj );
group = matlab.mixin.util.PropertyGroup( props );
end
The CustomDisplay mixin then displays only the group returned by getPropertyGroups() when disp() and display() are called. Since the properties() function called in getPropertyGroups() is the new "override", the group is displayed in sorted order.
Hope this helps someone!
Edit: added a public gist at github. https://gist.github.com/wwarriner/f189373bf40cc741f6d945165a85e115
3 Kommentare
Alexandru Bitca
am 10 Mär. 2020
Thank you so much for this! It works like a treat.
William Warriner
am 10 Mär. 2020
Happy to help! Adding a public gist on github.com as well.
Benjamin Gaudin
am 15 Okt. 2020
You can also override
function value = fields( obj )
value = sort( builtin( "fields", obj ) );
end
Daniel Shub
am 18 Jun. 2011
0 Stimmen
Why not just overload fieldnames to return sort(fieldnames)?
1 Kommentar
Ellis King
am 11 Aug. 2011
Andrew Newell
am 18 Jun. 2011
According to the documentation, you could add a property using a command like
Pa = hObj.addprop('a');
and later delete the property using
delete(Pa);
As for the order of names - even easier than overloading fieldnames would be to sort afterwards:
fn = sort(properties(hObj))'
2 Kommentare
Ellis King
am 11 Aug. 2011
Brett
am 24 Aug. 2011
Incidentally, if you forgot to save the handle Pa, it is still possible to delete the property 'a' using
delete(hObj.findprop('a'));
Steven Lord
am 14 Okt. 2020
I would be very wary of overloading properties or methods for your object.
There may be an easier way to do it, but you can query the metadata about a property and ask if it is "fixed" (defined in a properties block in the classdef file) or dynamic. When you ask for information about a property using findprop information about a fixed property is returned in a meta.Property object while information about a dynamic property is returned in a meta.DynamicProperty object. There's probably a more sophisticated way to create the property groups, but I wanted to get a quick example written before lunch. See the attached object.
y = example9777(5) % no dynamic properties yet
setDynamicProperty(y, 'Aardvark', 42)
y % one dynamic property
setDynamicProperty(y, 'Zebra', 999)
y % Zebra comes after Aardvark alphabetically
setDynamicProperty(y, 'Mouse', 'Good dog!')
y % Mouse was created after Zebra but comes before it alphabetically
% Yes, I am a fan of the Dresden Files
1 Kommentar
Benjamin Gaudin
am 15 Okt. 2020
Bearbeitet: Benjamin Gaudin
am 15 Okt. 2020
Excellent. Thank you for this answer. However here, properties( y ) or fieldnames( y ) will still return properties in a random order.
Kategorien
Mehr zu Data Type Identification finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!