How to avoid recursion in property set functions

I have an application where I would like to perform some additional operations when a property of a handle class is changed. For this purpose I thought I would use a property set method. Unfortunately when I do this, and the property set function uses another of the object's methods to assign the property value, I get an infinite recursion.
The documentation for property set methods states that property set methods are not called recursively, but this doesn't seem to apply if the property set method uses another of the objects methods to assign the property.https://www.mathworks.com/help/matlab/matlab_oop/property-set-methods.html
The recursion can be avoided if all of the code leading up to the property assignment, along with the property assignment are all contained just in the property set method. This can make the property set method rather bulky though.
Is there is some way to assign the property in another of the object's methods without encountering the inifinite recursion?
Also, am I misunderstanding the documentiation, regarding the set functions not being called recursively, or is this a bug?
The behavior is illustrated in the two highly simplified examples below.
In this implementation where everything is self contained in the set.a method everything works fine
h = myclassAlt
h =
myclassAlt with properties: a: []
h.a = 3
h =
myclassAlt with properties: a: 3
But here, where the property a is assigned indirectly set.a uses the object's method assignVal to do the acutal assignment, we get an infinite recursion (until it runs out of memory)
h = myclass
h =
myclass with properties: a: []
h.a = 3
Out of memory. The likely cause is an infinite recursion within the program.

Error in myclass/assignVal (line 15)
obj.a = aClipped;

 採用された回答

Matt J
Matt J 2023 年 10 月 18 日
編集済み: Matt J 2023 年 10 月 18 日

0 投票

The recursion can be avoided if all of the code leading up to the property assignment, along with the property assignment are all contained just in the property set method.
Or, you can offload just the code leading up to the property assignment:
classdef myclass < handle
properties
a % property to be set using set method
end
methods
function set.a(obj,val)
% set method for property a
obj.a=obj.modifyVal(val);
end
function newval=modifyVal(obj,val)
% perform the value modification
newval = min(val,5);
end
end
end

5 件のコメント

Jon
Jon 2023 年 10 月 18 日
編集済み: Jon 2023 年 10 月 18 日
Thanks for your suggestion on this. Still seems like a bit of a work around, but it is not that bad.
So I guess the statement in the documention that:
"Set Method Usage
  • Set methods are not called recursively."
Is not exactly true, it seems they are only not called recursively if they are self contained within the set method.
Matt J
Matt J 2023 年 10 月 18 日
Is not exactly true, it seems they are only not called recursively if they are self contained within the set method.
I'm not a computer scientist, but I believe the canonical definition of recursion is when a function makes a call to itself. If you offload the call to another function, it's not recursion anymore.
Jon
Jon 2023 年 10 月 18 日
Also, in my application, in some cases, the property should not be set to the new value, and should retain its old value. If it weren't for the recursion problem, this could easily be handled within the secondary function, simply by not assigning the new value.
With the approach of offloading everything but the assignment, it is not so neat. This could be addressed by having the other method get the current value, and then return it if it is not to be changed and then having the set property method reassign it to the same value. This would work but doesn't make the design intent obvious.
Matt J
Matt J 2023 年 10 月 18 日
編集済み: Matt J 2023 年 10 月 18 日
I don't really see the appeal of a secondary function if you are going to do every last step in it. All you achieve that way is a renaming of the function where the code resides from set.a() to something else.
Jon
Jon 2023 年 10 月 18 日
I agree, and have now just gone with putting it all in the set.xxx method.
Thanks so much for your help with this.
I'll accept this answer soon, but just wanted to leave it open for a little while to see if anyone else could offer any insights into this behavior.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeEnvironment and Settings についてさらに検索

製品

リリース

R2023b

質問済み:

Jon
2023 年 10 月 18 日

コメント済み:

Jon
2023 年 10 月 18 日

Community Treasure Hunt

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

Start Hunting!

Translated by