I'm writing a class definition that uses listeners to modify an object when certain properties are set. Like so:
classdef MyObject < handle
properties (SetObservable)
orientation = 'h'; % h = horizontal, v = vertical, o = other
length
width
end
methods
% Constructor
function mo = MyObject(o)
mo.orientation = o;
addlistener(mo, 'orientation', 'PreSet', @mo.changeOrientation);
end
% Change Orientation Listener
function changeOrientation(mo, src, evnt)
celldisp(src);
celldisp(evnt);
% I want a way to access newor here
if mo.orientation == 'h' && newor == 'o'
tempw = mo.width
mo.width = mo.length
mo.length = tempw;
end
end
% Setter
function set.orientation(mo, newor)
mo.orientation = newor;
end
end
end
I want to be able to use the variable newor when I set the orientation. How do I pass the new orientation variable to the changeOrientation method?
I want to avoid moving the contents of changeOrientation
into the set.orientation
method because Matlab complains about properties (length and width) potentially not being initialized.
EDIT length is NOT dependent on orientation. I just need to swap length and width when the orientation changes. In other cases, the user should be able to set length or width to any positive value.
You cannot do this as the PreSet listener is just that, a listener. The data passed to the listener callback never makes it way back to the object and modifying its value within your listener has no influence.
The purpose of using a PreSet listener is to get the value of the property before it is changed, but not to modify any values before they are actually assigned.
In the code that you have posted, I would likely just do any validation/modification of orientations within the set.orientation
method of your class.
function updateLength(mo)
% Change mo.length here and others based on mo.orientation
end
function set.orientation(mo, newor)
% validate newor
if dovalidation(newor)
mo.orientation = newor;
else
error('invalid!');
end
% Now trigger a "callback"
mo.updateDependentVariables()
end
EDIT
Based on your comment, probably the better way to go about this is to make length
have a shadow property length_
that holds the value the user assigns to length
. When the user requests the value of length
it can either return this stored value (if orientation == 'v') or the width
(if orientation == 'h')
classdef MyObject
properties (Dependent)
length % Can be either `width_` or `length_`
width % Can be either `width_` or `length_`
end
properties
orientation
end
properties (Access = 'protected')
length_ = 12
width_ = 10
end
methods
function mo = MyObject(o)
mo.orientation = o;
end
function set.orientation(mo, newor)
% If the user supplies an "o" flip the orientation
if strcmpi(newor, 'o')
if strcmpi(mo.orientation, 'v')
newor = 'h';
else
newor = 'v';
end
end
mo.orientation = newor;
end
function set.length(mo, value)
if strcmpi(mo.orientation, 'h')
self.length_ = value;
else
self.width_ = value;
end
end
function set.width(mo, value)
if strcmpi(mo.orientation, 'h')
self.width_ = value;
else
self.length_ = value;
end
end
function res = get.width(mo)
switch lower(mo.orientation)
case 'h'
res = mo.width_;
case 'v'
res = mo.length_;
otherwise
error('Invalid orientation');
end
end
function res = get.length(mo)
switch lower(mo.orientation)
case 'h'
res = mo.length_;
case 'v'
res = mo.width_;
otherwise
error('Invalid orientation');
end
end
end
end
This way you don't have to explicitly update length
when you change the orientation.
As a side note, I would not use length
as a property as that gets a little confused with the built-in function length
.