Creating a hard link among properties of an object?
이전 댓글 표시
Hello,
I have a class called Module that has 3 properties: InternalVariables, ExternalVariables, and AllVariables. InternalVariables and ExternalVariables both contain symbolic column vectors. I want to define AllVariables as the superposition of InternalVariables and ExternalVariables, and if I change either InternalVariables or ExternalVariables, AllVariables gets updated automatically. Is there a way to do this by using a hard link?
Thank you,
Kevin
채택된 답변
추가 답변 (1개)
NOTE: well, I spent an hour stuck in a mall with a tornado warning, so I had a little time to extend my first example. See EDIT below.
Did you try using setters and getters for these properties (in conjunction with dependent properties)? If they are stored in structs (and not as public/private/etc groups of properties), you may have to use subsasgn / subsref / substruct, etc.
EDIT : here is a new version of my previous example, which delegates indexing appropriately (I suppose, but I didn't have time to test) when fields of allVars contain arrays or structs.
classdef TestClass < handle
properties
intVars
extVars
allVars
end
methods
function obj = TestClass()
obj.intVars = struct( 'aInt', 3, 'bInt', 20:30, 'c', 7 ) ;
obj.extVars.dExt = struct( 'x', -2, 'y', 48 ) ;
obj.extVars.eExt = {'Hello', 'World'} ;
obj.extVars.c = 8 ;
end
function value = subsref( obj, S )
if length(S) > 1 && all( [S(1:2).type] == '.' ) && ...
strcmp( S(1).subs, 'allVars' )
is_int = isfield( obj.intVars, S(2).subs ) ;
is_ext = isfield( obj.extVars, S(2).subs ) ;
if is_int && is_ext
valueInt = obj.subsref_delegate( obj.intVars.(S(2).subs), S ) ;
valueExt = obj.subsref_delegate( obj.extVars.(S(2).subs), S ) ;
value = struct( 'int', valueInt, 'ext', valueExt ) ;
elseif is_int
value = obj.subsref_delegate( obj.intVars.(S(2).subs), S ) ;
else
value = obj.subsref_delegate( obj.extVars.(S(2).subs), S ) ;
end
else
value = builtin( 'subsref', obj, S ) ;
end
end
function obj = subsasgn_TODO( obj, S, value )
% .. your move.
end
end
methods (Static)
function value = subsref_delegate( x, S )
if length( S ) > 2
value = builtin( 'subsref', x, S(3:end) ) ;
else
value = x ;
end
end
end
end
With that..
>> tc = TestClass() ;
>> tc.intVars
ans =
aInt: 3
bInt: [20 21 22 23 24 25 26 27 28 29 30]
c: 7
>> tc.extVars
ans =
dExt: [1x1 struct]
eExt: {'Hello' 'World'}
c: 8
>> tc.extVars.dExt.x
ans =
-2
>> tc.allVars.aInt
ans =
3
>> tc.allVars.bInt
ans =
20 21 22 23 24 25 26 27 28 29 30
>> tc.allVars.bInt(7)
ans =
26
>> tc.allVars.c % c is a common property => output struct with int/ext values.
ans =
int: 7
ext: 8
>> tc.allVars.eExt{2}
ans =
World
>> tc.allVars.dExt.y
ans =
48
댓글 수: 4
Kevin Bachovchin
2014년 5월 12일
Just edited my answer with an example. If it answers your question, still wait a day or so before accepting the answer, as others (like Matt J) might have good insights and/or a better approach to propose.
PS: you probably understood that we are overloading subsref and subsasgn, to catch accesses to allVars's fields. If you don't understand how this works, create the object tc:
>> tc = TestClass() ;
and place a break point at the beginning of subsref (place cursor on the line which starts with if length( S ) .., and press F12). Then evaluate
>> tc.intVars.aInt
Once in the debugger, look at the struct S and you will understand the logic (if not, ask me again). Note that the else clause, which is evaluated in situations that we don't want to manage (i.e. when the user is not indexing a field of allVars), with the call
... = builtin( 'subsref', ..
is just delegating the management of the indexing to the builtin subsref (meaning not our overloaded version).
Sean de Wolski
2014년 5월 14일
Interesting comment on the tornado warning - I wonder if it was the same one that kept me at the hotel yesterday outside of Detroit.
Cedric
2014년 5월 14일
Ah! Yes, I am in Ann Arbor ;-)
카테고리
도움말 센터 및 File Exchange에서 Handle Classes에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!