필터 지우기
필터 지우기

Property listener with OOP

조회 수: 2 (최근 30일)
Trevor Harris
Trevor Harris 2016년 9월 7일
댓글: Trevor Harris 2016년 9월 21일
Hello all,
I'm not exactly sure what I'm supposed to be asking here, so forgive me if I'm way off base. I have an object created in matlab with three properties. The class is called an nUnit, and the properties are value, unit, and unitVec. Both the unit and unitVec are heavily related to one another. So, if the user modifies the .unit, I wish for the .unitVec to be automatically updated and vice versa.
I have the conversion functions written, but how do I trigger them to run? I've read a lot about listeners and the like, but I can't seem to find a proper example for a function that would get triggered if a property is modified. Below is my class definition file. Thank you for your time!
Trevor
classdef nUnit
%NUNIT Create numerical unit class
%
% A = NUNIT(VALUE, UNITSTRING)
% A = NUNIT(VALUE, UNITVEC)
% Inputs:
% VALUE: Numeric scalar or array
% UNITSTRING: String of accepted unit strings
% UNITVEC: 1x9 numeric array of base unit powers
%
properties
value
unit
unitVec
end
methods
function nU = nUnit(value,unit)
% ==============================================================================
% Constructor - Create an nUnit
% ==============================================================================
if ~isnumeric(value) || isempty(value); error('input VALUE must be a non-empty numeric'); end
% If value is 1-dimensional, force vertical concatenation
if any(1 == size(value))
value = value(:);
end
if ~(ischar(unit) ||...
(isnumeric(unit) &&...
all(size(unit) == [1, 9]))); error('input UNIT must be a string or unitVector'); end %#ok<ALIGN>
if ischar(unit) % Unit string is inputed
[nU.unitVec, valueMult] = unit2vec(unit);
nU.unit = vec2unit(nU.unitVec);
nU.value = value * valueMult;
else % Unit vector is inputed - Base units only
nU.unitVec = unit;
nU.unit = vec2unit(unit);
nU.value = value;
end
end
% ==============================================================================
% Functions that only modify value property
% ==============================================================================
function nUnitA = diff(varargin); nUnitA = genValueFun(@diff, varargin{:}); end
function nUnitA = unique(varargin); nUnitA = genValueFun(@unique, varargin{:}); end
function nUnitX = genValueFun(functionH, nUnitX, varargin)
nUnitX.value = feval(functionH, nUnitX.value, varargin{:});
end
% ==============================================================================
% Overload Numel for O-O compatability
% Source: http://www.mathworks.com/matlabcentral/answers/101955-why-do-i-receive-errors-when-overloading-subsref-for-types-and-for-matlab-classes
% ==============================================================================
function n = numel(varargin)
n = 1;
end
% ==============================================================================
% Functions that query the value property
% ==============================================================================
function [varargout] = size(varargin)
varargout = genValueQueryFun(@size, varargin{:});
varargout = {varargout};
end
function [varargout] = length(varargin)
varargout = genValueQueryFun(@length, varargin{:});
varargout = {varargout};
end
function [varargout] = genValueQueryFun(functionH, nUnitX, varargin)
varargout = feval(functionH, nUnitX.value, varargin{:});
varargout = {varargout};
end
end
end

채택된 답변

Adam
Adam 2016년 9월 7일
편집: Adam 2016년 9월 7일
I use dependent properties for this, e.g.
properties
value
end
properties( Dependent )
unit
unitVec
end
properties( Access = private )
unit_;
unitVec_;
end
methods
function obj = set.unit( obj, unit )
unit_ = unit;
updateUnitVecFromUnit( obj );
end
function unit = get.unit( obj )
unit = obj.unit_;
end
function obj = set.unitVec( obj, unitVec )
unitVec_ = unitVec;
updateUnitFromUnitVec( obj );
end
function unitVec = get.unitVec( obj )
unitVec = obj.unitVec_;
end
end
methods( Access = private )
function updateUnitFromUnitVec( obj )
obj.unit_ = f( obj.unitVec_ );
end
function updateUnitVecFromUnit( obj )
obj.unitVec_ = f2( obj.unit_ );
end
end
There may be some errors in there as I did it off the top of my head, but the general idea is that only a dependent property is allowed to (or rather should do) alter other properties in its set function so you use a double property solution with a private property for each that actually stores the value and a dependent property which is publicly visible and whose set function will then update the other property also.
It is very important though that you update unit_ and unitVec_ in the functions as shown above otherwise you will have a circular set of calls that will lead you to infinite recursion! My code above just uses placeholder functions f and f2 instead of whatever it is you have already written to update one property from the other.
You could use a property listener. I do in many many cases, but not usually if I am doing something like this.
  댓글 수: 1
Trevor Harris
Trevor Harris 2016년 9월 21일
Thanks so much, that's perfect! Very helpful.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Interactive Control and Callbacks에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by