Presentation is loading. Please wait.

Presentation is loading. Please wait.

@ReferAssignGetSet February 21, me. berkeley

Similar presentations


Presentation on theme: "@ReferAssignGetSet February 21, me. berkeley"— Presentation transcript:

1 @ReferAssignGetSet February 21, 2008 http://jagger. me. berkeley
@ReferAssignGetSet February 21, Copyright , Andy Packard. This work is licensed under the Creative Commons Attribution-ShareAlike License. To view a copy of this license, visit or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.

2 @ReferAssignGetSet Many ideas of
get, set, subsref, subsasgn will to carry over to all classes we write. For example, Reference of M.Value is the same as get(M,’Value’) Multi-depth subsref has specific recursive meaning Assignment of M.Value=B is the same as set(M,’Value’,B) Multi-depth subsasgn has specific recursive meaning In some cases, () reference and assignment should be handled by the built-in methods for Matlab arrays set should work with or without output arguments Special Matlab-like conventions for get and set should be followed Calls with 1-input argument Property names can be partially specified Multiple args in set(A,P1,V1,P2,V2) This is a good motivation to write a class that handles all of this functionality, and all other classes will simply inherit this.

3 @ReferAssignGetSet Questions/Options for a given class
Is property reference allowed, as in Object.Property Is property assignment allowed, as in Object.Property = Value Is () reference allowed, as in Object(Idx1,Idx2) if so, are builtin methods used, or does the class programmer supply the reference method? Is () assignment allowed, as in Object(Idx1,Idx2) = Value if so, are builtin methods used, or does the class programmer supply the assignment method? Is {} reference allowed, as in Object{Idx1,Idx2} Is {} assignment allowed, as in Object{Idx1,Idx2} = Value Does set use assignin when called with no output arguments? set(A,Prop,Value) %uses inputname, overwrites A A = set(A,Prop,Value) % overwrites A, directly B = set(A,Prop,Value) % A unchanged

4 @ReferAssignGetSet Constructor (see actual code) just keeps track of the options to handle decisions for each of the cases described. function A = ReferAssignGetSet(InputArgsSpecifiers) A.PropertyRef = 'followGet'; % or 'disallow' A.PropertyAssign = 'followSet'; % 'disallow' A.ParenRef = 'ProgSupplied'; % 'builtin', 'disallow' A.ParenAssign = 'ProgSupplied'; % 'builtin', 'disallow' A.BraceRef = 'ProgSupplied'; % 'builtin', 'disallow' A.BraceAssign = 'ProgSupplied'; % 'builtin', 'disallow' A.AllowSetAssignin = 0; % or 1 A = class(A,'ReferAssignGetSet'); Also need general purpose versions of get, set, subsref, subsasgn

5 Folder layout @ReferAssignGetSet @class1 @class2 @class3 private
ReferAssignGetSet.m get.m set.m subsref.m subsasgn.m fieldnames.m class1.m GetSetPropertyInfo isvalid PrivateGet PrivateSet ParenthesisReference ParenthesisAssign BraceReference BraceAssign horzcat, vertcat smartpropmatch private @ReferAssignGetSet class2.m GetSetPropertyInfo Isvalid PrivateGet PrivateSet ParenthesisReference ParenthesisAssign OtherMethodsforclass2 @class1 class3.m GetSetPropertyInfo Isvalid PrivateGet PrivateSet OtherMethodsforclass3 @class2 @class3

6 Example child class: @point
function A = point(X,Y,varargin) S.X = X; S.Y = Y; % point in 2-dim Euclidean space PropRef = 'followGet'; % or 'disallow' PropAssign = 'followSet'; % or 'disallow' ParenRef = 'builtin'; % or 'builtin' or 'disallow' ParenAssign = 'builtin'; % or 'builtin' or 'disallow' BraceRef = 'disallow'; % or 'ProgSupplied' or 'builtin' BraceAssign = 'disallow'; %or 'ProgSupplied‘, 'builtin' ASA = 1; % or 0, ASA-> AllowSetAssignin B = ReferAssignGetSet(PropRef,PropAssign,... ParenRef,ParenAssign,BraceRef,BraceAssign,ASA); A = class(S,'point',B); lvin = length(varargin); if lvin>0 && ceil(lvin/2)==floor(lvin/2) A = set(A,varargin{:}); end

7 @ReferAssignGetSet get and set call the child’s GetSetPropertyInfo
function [GPN,SPN,SPD] = GetSetPropertyInfo(A) % Return a N-by-1 cell array of GET Prop Names % Return a M-by-1 cell array of SET Prop Names % Return a M-by-1 cell array of SET Property % Descriptions get & set also call child’s PrivateGet and PrivateSet function Value = PrivateGet(Object,GPropName) function B = PrivateSet(Object,SPropName,Value)

8 @point/GetSetPropertyInfo.m
function [GPN,SPN,SPD] = GetSetPropertyInfo(A) CommonNames = {'XCoord';'YCoord'}; OnlyGet = {'Radius';'Angle'}; OnlySet = cell(0,1); % empty cell GPN = [CommonNames;OnlyGet]; % gettable properties SPN = [CommonNames;OnlySet]; % settable properties SPD = {'XCoordinate of Point';'YCoordinate of Point'};

9 Pseudocode for get.m function V = get(A,Property)
[GPN,SPN,SPD] = GetSetPropertyInfo(A); if nargin==2 FullPropName = smartpropmatch(Property,GPN); V = PrivateGet(A,FullPropName); else % nargin==1 % Create structure V1 with fieldnames equal % to the property names in GPN. Then fill % the values of the struct with the values % calling PrivateGet. if nargout==1; V = V1; else; disp(V1) end

10 Pseudocode for PrivateGet.m
function V = PrivateGet(A,FullPropName) switch FullPropName case PropertyName1 V = % extract Property1 from fields of A case PropertyName2 V = % extract Property2 from fields of A case ... case PropertyNameK V = % extract PropertyK from fields of A Otherwise error(’Unknown Property’); end

11 @point/PrivateGet.m function V = PrivateGet(A,FullPropName)
switch FullPropName case 'XCoord' V = A.X; case 'YCoord' V = A.Y; case 'Radius' V = norm([A.X A.Y]); case 'Angle' V = atan2(A.Y,A.X); otherwise error([FullPropName ': Unknown Property.']); end

12 @point/PrivateSet.m function A = PrivateSet(A,FullPropName,Value)
switch FullPropName case 'XCoord' if isa(Value,'double') && isscalar(Value) A.X = Value; else error('XCoordinate should be real scalar'); end case 'YCoord' A.Y = Value; error('YCoordinate should be real scalar'); otherwise error([FullPropName ': Unknown Property']);

13 Similar for Assignment/Reference
General purpose subsref, subsasgn reside they call the object’s specific reference and assignment methods ParenthesisAssign ParenthesisReference BraceAssign BraceReference In this way, one version of subsref and subsasgn address the issues Proper relation to get/set Deep references/assignments Similarly, there should be tight integration with horzcat and vertcat, but at this point, we leave that to the programmer...

14 @ReferAssignGetSet/subsref
function B = subsref(A,L) ReAsGeSe = A(1); switch L(1).type case '.' if isequal(ReAsGeSe.PropertyRef,'followGet') B = get(A,L(1).subs); else error('dot(.) reference not allowed. Use GET.'); end case '()' case '{}' if length(L)>1 B = subsref(B,L(2:end));

15 @ReferAssignGetSet/subsref
function B = subsref(A,L) ReAsGeSe = A(1); switch L(1).type case '.' case '()' if isequal(ReAsGeSe.ParenRef,'builtin') B = builtin('subsref',A,L(1)); elseif isequal(ReAsGeSe.ParenRef,'ProgSupplied') B = ParenthesisReference(A,L(1).subs); else error('() reference is not allowed.'); end case '{}' if length(L)>1 B = subsref(B,L(2:end));

16 @ReferAssignGetSet/subsref
function B = subsref(A,L) ReAsGeSe = A(1); switch L(1).type case '.' case '()' case '{}' if isequal(ReAsGeSe.BraceRef,'builtin') B = builtin('subsref',A,L(1)); elseif isequal(ReAsGeSe.BraceRef,'ProgSupplied') B = BraceReference(A,L(1).subs); else error('{} reference is not allowed.'); end if length(L)>1 B = subsref(B,L(2:end));

17 @ReferAssignGetSet/subsasgn
function B = subsasgn(A,L,RHS) ReAsGeSe = A(1); switch L(1).type case '.' if isequal(ReAsGeSe.PropertyAssign,'followSet') if length(L)==1 B = set(A,L(1).subs,RHS); else tmp = get(A,L(1)); tmp = subsasgn(tmp,L(2:end),RHS); B = set(A,L(1).subs,tmp); end error('dot(.) assignment not allowed. Use SET.'); othercases

18 @ReferAssignGetSet/subsasgn
case '()' if isequal(ReAsGeSe.ParenAssign,'builtin') if length(L)==1 B = builtin('subsasgn',A,L(1),RHS); else tmp = builtin('subsref',A,L(1)); tmp = subsasgn(tmp,L(2:end),RHS); B = builtin('subsasgn',A,L(1),tmp); end elseif isequal(ReAsGeSe.ParenAssign,'ProgSupplied') B = ParenthesisAssign(A,L(1).subs,RHS); tmp = subsref(A,L(1)); B = ParenthesisAssign(A,L(1).subs,tmp); error('() assignment is not allowed.');

19 Examples using @point (try these)
>> p = point(2,4); >> get(p) >> get(p,’Radius’) >> p.Angle >> p.An >> get(p,’Angle’) >> p.XCoord = 4; >> p.Angle*180/pi % convert to degrees >> set(p) >> p2 = point(-5,10); >> M = [p p2;point(1,1) point(3,-3)]; >> M(2,1).XCoord >> M(2,1).XCo = 3; >> M(2,1).An Why do these work? New Challenge: After you check these commands out, make Radius and Angle settable. Rule would be that when you change Radius, the Angle is unchanged, and similar for changing Angle. In each case, the underlying “real” data (X and Y) have to get correctly modified.


Download ppt "@ReferAssignGetSet February 21, me. berkeley"

Similar presentations


Ads by Google