setter fails/ gets passed by
조회 수: 3 (최근 30일)
이전 댓글 표시
As the help file says:
Setter methods ( set.variable ) do not get called when assigning the target value inside this function as this could result in endless recursion.
Now I had the case, that I assig that very target value but it is from another instance of the class. But that is obscure. Cause it changes the value without doing the things that are nessesary leading to an inconsistent program state.
From my perspective this is a kind of bug or am I wrong?
classdef test < handle
properties
a
ref_To_Another_Instance_Of_This_Class
end
methods
function this = test( isSlave )
if nargin == 0 % prevent endless recursion
this.ref_To_Another_Instance_Of_This_Class = test( true );
this.a = 3;
end
end
function set.a( this , newA )
disp( 'setter method called' )
this.a = newA;
this.ref_To_Another_Instance_Of_This_Class.a = newA;
end
end
end
댓글 수: 0
답변 (2개)
Jacob Halbrooks
2014년 1월 29일
I believe using the code below reproduces the unexpected behavior you write about, where a set on the top-level object does not propagate through all of the children:
>> t = test;
>> t.ref_To_Another_Instance_Of_This_Class = test;
>> t.a = 5;
>> t.ref_To_Another_Instance_Of_This_Class.a
ans =
5
>> t.ref_To_Another_Instance_Of_This_Class.ref_To_Another_Instance_Of_This_Class.a
ans =
3
This occurs because setting the child's "a" property in the set method of "a" bypasses the child's set method and just updates the property. I think this behavior makes sense with the understanding that the set function is defined on the class, and its requirement is that it not be re-entered.
In order to propagate the set all the way through the children, I would suggest the approach below, where "a" is made Dependent (you should get a Code Analyzer warning in your class advising this) and define a new method to perform the work of updating properties:
classdef test2 < handle
properties(Dependent)
a
end
properties
ref_To_Another_Instance_Of_This_Class
end
properties(Access=private)
pA;
end
methods
function this = test2( isSlave )
if nargin == 0 % prevent endless recursion
this.ref_To_Another_Instance_Of_This_Class = test2( true );
this.a = 3;
end
end
function set.a( this , newA )
disp( 'setter method called' )
this.updateA(newA);
end
function a = get.a(this)
a = this.pA;
end
function updateA(this, newA)
this.pA = newA;
if ~isempty(this.ref_To_Another_Instance_Of_This_Class)
this.ref_To_Another_Instance_Of_This_Class.updateA(newA);
end
end
end
end
This class can now be used to set "a" all the way through:
>> t2 = test2;
>> t2.ref_To_Another_Instance_Of_This_Class = test2;
>> t2.a = 5;
>> t2.ref_To_Another_Instance_Of_This_Class.a
ans =
5
>> t2.ref_To_Another_Instance_Of_This_Class.ref_To_Another_Instance_Of_This_Class.a
ans =
5
댓글 수: 0
참고 항목
카테고리
Help Center 및 File Exchange에서 Construct and Work with Object Arrays에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!