How to execute a function after the value of a property changed? Problems with callback function

35 views (last 30 days)
Hi, I would like to execute a function every time a particular property of an object has changed. More specifically, I have two properties in my class (PW - not observable, PMV Observable). I would like PMV to change every time PW changes. Below is how far I have gotten in order to achieve this:
*START CODE*
classdef RB < handle
properties
PW = [];
end
properties(SetObservable)
PMV = [];
end
methods
function this = RB()
addlistener(this,'PMV','PostSet',@RB.ChgPMV);
end
function ChgPMV(this)
disp('got here');
this.PW = this.PMV ./ sum(this.PMV);
end
end
end
*END CODE*
Unfortunately it doesnt work... This is what I get:
>> a=RB() a = RB with properties:
PW: []
PMV: []
>> a.PMV=[10,20]
Warning: Error occurred while executing callback:
Undefined function 'RB.ChgPMV' for input arguments of type 'meta.property'.
a =
RB with properties:
PW: []
PMV: [10 20]
>>
My question now is: How do I need to change the code such that the ChgPMV function executes? Thank you for any hint Sven

Answers (2)

per isakson
per isakson on 7 Dec 2013
Edited: per isakson on 7 Dec 2013
There are two problems
  • @RB.ChgPMV (this call would work with static methods) [see the answer of Sven]
  • function ChgPMV( this ) Matlab adds a couple of arguments, which need to be matched by input arguments
Now
>> a=RB();
>> a.PMV = 1;
got here
where
classdef RB < handle
properties
PW = [];
end
properties( SetObservable )
PMV = [];
end
methods
function this = RB()
addlistener( this,'PMV','PostSet',@this.ChgPMV);
end
function ChgPMV( this, varargin )
disp('got here');
this.PW = this.PMV ./ sum(this.PMV);
end
end
end

Sven
Sven on 6 Dec 2013
Edited: Sven on 6 Dec 2013
If all of the observation of PMV is done by the RB class itself, so there's actually a better/cleaner way to do what you're trying to do. Here I just make PMV a simple property and PW a dependent property. Then I use the .set() method of PMV to perform the update of PW.
Does this do what you expected?
classdef RB < handle
properties
PMV = [];
end
properties (Dependent)
PW
end
methods
function set.PMV(this, newVal)
this.PMV = newVal;
this.ChgPMV()
end
function ChgPMV(this)
disp('got here');
this.PW = this.PMV ./ sum(this.PMV);
end
end
end
There's nothing stopping you from making PMV SetObservable for other purposes, but it's not necessary to achieve what you described.
Oh, and if you really wanted to make your original example work, just use this line in your constructor:
addlistener(this,'PMV','PostSet',@(src,eventData)this.ChgPMV);
You'll notice that I changed RB (class name) to this (the object in scope that you want to listen to), and declared the two default input arguments to the listener which you don't really use but would be added automatically if you didn't declare them)
I hope that answered your question. If so, remember to hit "accept".
Thanks, Sven.

Categories

Find more on Interactive Control and Callbacks in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!