Referencing an object property within the set method for a different property
10 views (last 30 days)
Show older comments
I have the following custom class definition:
classdef PlotParameters < handle
% properties that affect how data is plotted
properties
Prop1 (1,1) double
Prop2 (1,1) double
end
% properties that don't affect how data is plotted
properties
Prop3 (1,1) string
Prop4 (1,1) string
end
% The HoldUpdatePlot private property is set to true by class methods
% that updated multiple properties at once. When this property is true,
% the UpdatePlot event is not fired. When this property is changed from
% true to false, the UpdatePlot event is always fired (see the set
% method for HoldUpdatePlot).
properties (Access = private)
HoldUpdatePlot (1,1) logical = false
end
% The UpdatePlot event is fired whenever the object properties that
% affect how data is plotted (i.e. Prop1 and Prop2) are updated.
events
UpdatePlot
end
% CONSTRUCTOR METHOD
methods
function obj = PlotParameters(opt)
arguments
opt.Prop1 (1,1) double = 1
opt.Prop2 (1,1) double = 1
opt.Prop3 (1,1) string = ""
opt.Prop4 (1,1) string = ""
end
obj.HoldUpdatePlot = true;
obj.Prop1 = opt.Prop1;
obj.Prop2 = opt.Prop2;
obj.Prop3 = opt.Prop3;
obj.Prop4 = opt.Prop4;
obj.HoldUpdatePlot = false;
end
end
% PROPERTY SET METHODS
methods
function set.Prop1(obj, NewProp1Value)
arguments
obj (1,1) PlotParameters
NewProp1Value (1,1) double
end
% fires the UpdatePlot event
obj.Prop1 = NewProp1Value;
if ~obj.HoldUpdatePlot
notify(obj,'UpdatePlot');
end
end
function set.Prop2(obj, NewProp2Value)
arguments
obj (1,1) PlotParameters
NewProp2Value (1,1) double
end
% fires the UpdatePlot event
obj.Prop2 = NewProp2Value;
if ~obj.HoldUpdatePlot
notify(obj,'UpdatePlot');
end
end
function set.HoldUpdatePlot(obj, NewHoldUpdatePlotValue)
% fires the UpdatePlot event when HoldUpdatePlot is switched from true to false
arguments
obj (1,1) PlotParameters
NewHoldUpdatePlotValue (1,1) logical
end
if ~NewHoldUpdatePlotValue && obj.HoldUpdatePlot
obj.HoldUpdatePlot = NewHoldUpdatePlotValue;
notify(obj,'UpdatePlot');
else
obj.HoldUpdatePlot = NewHoldUpdatePlotValue;
end
end
end
% GENERAL METHODS
methods
function ResetAllProperties(obj)
% resets all properties to their default values
arguments
obj (1,1) PlotParameters
end
obj.HoldUpdatePlot = true;
obj.Prop1 = 1;
obj.Prop2 = 1;
obj.Prop3 = "";
obj.Prop4 = "";
obj.HoldUpdatePlot = false;
end
end
end
The idea is that I can have an external listener for the UpdatePlot event which will replot data when the relevant properties of the PlotParameters object are updated:
>> PlotParametersObject = PlotParameters();
>> addlistener(PlotParametersObject,'UpdatePlot',@(src,evnt)disp("Property changed - data will be replotted!"));
>> PlotParametersObject.Prop1 = 5;
Property changed - data will be replotted!
However, if multiple properties are being updated at once, I don't want the UpdatePlot event to be fired more than once. So there is a private property ("HoldUpdatePlot") that will prevent the UpdatePlot event from firing if it is set to true. This is used by class methods such as ResetAllProperties to stop the UpdatePlot event from firing until all property updates have been made:
>> PlotParametersObject.ResetAllProperties();
Property changed - data will be replotted!
Notice how only one notification is printed, even though multiple properties were updated.
Although the code is working as intended, MATLAB shows warnings in the set methods for Prop1 and Prop2 (on lines 59 and 71). These set methods reference a property other than the property being set (HoldUpdatePlot), and the text of the warning is the following:

I tried saving and loading a PlotParameters object to/from a file, and I didn't have any issues. However, the language in the warning suggests that that might not always be the case. Unfortunately, I really need to prioritize stability with this code, and the possiblity of it working one day and then not working the next day is not acceptable.
I can't think of a different way to structure the class which would avoid the warning while still achieving the functionality I need. Is there anyone out there who's smarter than I am and can suggest a better way to do what I'm trying to do?
Alternatively, is there anyone out there who can say difinitively, "That code will always work - you should just ignore the warning"?
0 Comments
Accepted Answer
Matt J
on 6 Mar 2023
Edited: Matt J
on 6 Mar 2023
This may seem cumbersome to you, but the robust way to deal with this is to make any property that can trigger an event Dependent. Because Dependent properties are not set when loading an object from a file, you don't need to worry about any kind of event sequencing in that circumstance. For brevity's sake, I illustrate for only one such property Prop1:
classdef PlotParameters < handle
% properties that affect how data is plotted
properties (Hidden,Access=private)
Prop1_ (1,1) double %Holdd the data for Prop1
end
properties (Access=private)
HoldUpdatePlot (1,1) logical = false
end
properties (Dependent)
Prop1
end
function val=get.Prop1(obj)
val=obj.Prop1_;
end
function set.Prop1(obj, NewProp1Value)
arguments
obj (1,1) PlotParameters
NewProp1Value (1,1) double
end
obj.Prop1_ = NewProp1Value;
if ~obj.HoldUpdatePlot
notify(obj,'UpdatePlot');
end
end
end
More Answers (1)
Matt J
on 4 Mar 2023
You can create a processNotification() method and do all the necessary property referencing there instead:
function processNotification(obj)
if ~obj.HoldUpdatePlot
notify(obj,'UpdatePlot');
end
end
function set.Prop1(obj, NewProp1Value)
arguments
obj (1,1) PlotParameters
NewProp1Value (1,1) double
end
% fires the UpdatePlot event
obj.Prop1 = NewProp1Value;
processNotification(obj);
end
function set.Prop2(obj, NewProp2Value)
arguments
obj (1,1) PlotParameters
NewProp2Value (1,1) double
end
% fires the UpdatePlot event
obj.Prop2 = NewProp2Value;
processNotification(obj);
end
3 Comments
Matt J
on 6 Mar 2023
I notice that there are no plot handle properties in your classdef. Shouldn't there be, since all this seems to be geared toward plot management?
If you had a handle property, you could have the processNotification() method first check if the handle (i.e., if the plot is exists), and abort if not. Then the status of the HoldPlotUpdate property wouldn't matter.
See Also
Categories
Find more on Environment and Settings in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!