I am trying to implement save/load functions in a MATLAB (R2009a) UI. My object implements a layout function that generates a user interface for the object. I am trying to implement the callbacks for the save/load buttons. The save button works and save the object out to a MAT file which can be loaded later.
My problem is implementing the callback for the load button. I cannot seem to get the load to load the data from the MAT file and update the properties of the new object. Any suggestions on where I am going wrong along with suggestions on how I might proceed is greatly appreciated.
The important code is my class definition file of course my actual object implements many more properties and methods but here is a skeleton of what I have
classdef myObj<handle
properties
image % property holds a matlab image matrix
objCount % number of objects in image
end
properties(Transient=true)
parent
children
end
methods
function myObj
% empty constructor
end
function load_object(self)
% ask user for file
[fileName, pathToFile]=uigetfile('*.mat','Select .mat file');
tmp = load(fullfile(pathToFile,fileName);
if isfield(tmp,'obj')
self = tmp.obj;
end
end
LayoutFcn(self) % UI layout function
end
end
The UI layout is defined in a seperate file LayoutFcn.m which basically looks like
function LayoutFcn(self)
% create figure window and add various UI elements
...
% create load button
self.children(end+1) = uipushtool('Parent',hToolbar, ... % set parent to current toolbar
'CData',iconRead('open-document.png'), ... % read icon image from file
'Tag','uiLoad', ...
'ClickedCallback',#(hObj,event)loadingMyObject(self,hObj,event));
% create save button
self.children(end+1) = uipushtool('Parent',hToolbar, ... % set parent to current toolbar
'CData',iconRead('save-document.png'), ... % read icon image from file
'Tag','uiSave', ...
'ClickedCallback',#(hObj,event)savingMyObject(self,hObj,event));
...
end
function loadingMyObject(self,hObj,event)
self.load_object; % call load_object method defined above in class definition
end
function savingMyObject(self,hObj,event)
[fileName,pathName]=uiputfile('.mat','Save object to MAT file');
obj = self;
save(fullfile(pahtName,fileName),'obj')
end
Note: I am using MATLAB R2009a.
The code doesn't throw any errors. The way I wrote the code the parent object (represented by self) does not get updated after the call to LOAD in the method load_object. SO, this has the desired effect:
>> var = myObj;
>> var.load_object;
However, if I use the loadingMyObject callback defined in LayoutFcn.m in this fashion
>> var = myObjl
>> var.LayoutFcn
-> click Load button to call _loadingMyObject_
doesn't affect var properties. That is var will still have its default property values after clicking the Load button.
Changing the load methods to use set as suggested by gnovice throws the following error
??? Error using ==> set
Conversion to double from FujiCalibration is not possible.
even though I have set/get methods for each property; as in
method set.image(self,II)
% ... some data validation code ...
self.image = II
end
Using a loop to set each field as suggested by Mr Fooz is not really an option as my full class has public constant that throw an error when they are set.
I am looking for a solution that would avoid me having to hand code setting each field individually. Although at this point it seems like the only possibility.
I believe Mr Fooz is right. The self variable passed to load_object is an object of type "myObj", but the line:
self = tmp.obj;
is simply overwriting the self variable with the structure stored in tmp.obj. Doing:
self.image = tmp.obj.image;
should instead invoke a set operator for the image property of object self. In the MATLAB documentation there is a sample class definition with a method called "set.OfficeNumber" that illustrates this.
In addition, the following line in your function savingMyObject may be unnecessary:
obj = self;
I think it might make most sense (and make the code a little clearer) if you used the name "obj" in place of the word "self" within your class code (as the documentation tends to do). "self" doesn't appear to be any kind of special keyword in MATLAB (like it may be in other languages). It's just another variable as far as I can tell. =)
EDIT #1:
If the prospect of having to set each property individually in your load_object method doesn't sound like fun, one way around it is if you have a SET method for your object that is designed like the SET method for handle graphics. That SET command can accept a structure input where each field name is a property name and each field value is the new value for that property. Then you would have one call like:
set(self,tmp.obj);
Quite a bit shorter, especially if you have lots of properties to set. Of course, you'd then have to write the new SET method for your object, but the shortened syntax may be worth the extra work if it comes in handy elsewhere too. =)
EDIT #2:
You may be able to use the loop Mr Fooz suggested in conjunction with a try/catch block:
fn = fieldnames(tmp.obj);
for i = 1:numel(fn),
try
self.(fn{i}) = tmp.obj.(fn{i});
catch
% Throw a warning here, or potentially just do nothing.
end
end
Don't assign values to self. All that does is replace the binding to the self variable in the scope of the method call. It does not call a magical copy constructor to replace the object reference in the caller. Instead, copy the fields into self. Try something like:
if isfield(tmp,'obj')
self.image = tmp.obj.image;
self.objCount = tmp.obj.objCount;
end
Combining Mr Fooz's and gnovice's suggestions, I added a SET function with the following definition
function set(self,varargin)
if isa(varargin{1},'FujiCalibration')
tmp = varargin{1};
fns = fieldnames(self);
for i = 1:length(fns)
if strcmpi(fns{i}(1:2),'p_')
self.(fns{i}) = tmp.(fns{i});
end
end
self.calibImage = tmp.calibImage;
else
proplist=fields(self);
for n=1:2:length(varargin)
tmp = proplist(strcmpi(proplist,varargin{n}));
value = varargin{n+1};
switch length(tmp)
case 0
msg = char(strcat('There is no ''', varargin{n}, '''property'));
error('FujiCalibration:setPropertyChk',msg)
case 1
tmp = char(tmp);
self.(tmp) = value;
end
end
end
end
I then modified the load_object method as suggested by gnovice by changing
self = tmp.obj
to
set(self,tmp.obj).
I need to make sure that properties with values I want to persist are prefixed with 'p_'.
Thanks to gnovice and Mr Fooz for their answers.
Related
I have created a very simple GUI in appdesigner (Matlab) with one dropdown menu. Additionally, I took the code that got generated (under 'Code View' tab) and pasted that in a normal .m file (because, I want to further add some more contents to this code). My question is how can I access certain variable from this self generated code, so that I can play with that value outside of the main class?
For example:
In App class, for this dropdown menu section, following line of code got generated:
app.ColorDropDown = uidropdown(app.UIFigure);
app.ColorDropDown.Items = {'Red', 'Blue', 'Yellow'};
app.ColorDropDown.Position = [277 178 140 22];
app.ColorDropDown.Value = 'Red';
Outside of this app class: Depending upon the value that was selected in this dropdown menu, I want to capture that in a normal variable, and show some other results based on the color selected
Thanks
It seems like the essence of your question is about sharing data between GUIs as you state you want to "show some other results based on the color selected".
Note: MATLAB documentation cautions: Do not use UserData property in apps you create with App Designer.
The documentation goes on to recommend approaches for sharing data among app designer apps and creating multiwindow apps in app designer.
For the sake of completeness, I'll provide a detailed example, different from the MATLAB documentation, of how this can be accomplished entirely within the App Designer.
Setup
I created 2 app designer apps, controlGUI.mlapp and plotGUI.mlapp. Running controlGUI() loads both mlapp files at once and then allows you to control aspects of the plotGUI from callbacks in the controlGUI. Of course, the plotGUI could do anything but I have it changing visual aspects of the plotted data.
Details
For simplicity, I am setting the controlGUI be the main application. I can do this be adding a property in controlGUI named PlotWindow and having it contain the output of calling plotGUI(); the other mlapp. I also have a callback function I recycle for the three dropdowns that updates a DATA property in the plotGUI. This DATA property has a listener attached that fires a callback to update the uiaxes object.
The plotGUI
The magic is really in this object. That is, I created a property named DATA and altered the access. By setting the property access SetObservable = true, we can then add a PostSet event listener, which I stored in a private property called dataChangedListener during the startupFcn.
properties (Access = public, SetObservable=true)
DATA % A struct with xdata, ydata, fields. Other line prop fields ok
end
properties (Access = private)
dataChangedListener % listener object for when DATA is changed.
end
Then the startup function, startupFcn, initializes the DATA property with some (arbitrary) data as struct then adds and enables the PostSet listener.
% Code that executes after component creation
function startupFcn(app, data)
if nargin < 2
% create a default dataset
data = struct();
data.xdata = linspace(0,1,1001);
data.ydata = sin(data.xdata.*2*pi*10);%10hz signal
data.color = app.Axes.ColorOrder(1,:);
end
app.DATA = data;
% plot the data
line(data, 'parent', app.Axes);
% add and enable PostSet event listener for the DATA property
app.dataChangedListener = addlistener(...
app,'DATA','PostSet', ...
#(s,e) app.updatePlot ...
);
app.dataChangedListener.Enabled = true;
end
The PostSet listener calls the method app.updatePlot(), so we have to add this method to our app. This method will get called whenever anything in app.DATA gets modified. So I created the "function" (as the Code Browser calls it) which simply deletes the axes children (the existing line) and uses the low-level version of line() to draw a primitive line based on the app.DATA struct object:
function updatePlot(app)
%clear plot
delete(app.Axes.Children);
% draw the new plot
line(app.DATA, 'parent', app.Axes);
end
Yes, line() will accept a struct which has field names that correspond to valid line properties but I can't seem to find the reference specifically. But if you read about the inputParser object... sorry, getting off topic.
The controlGUI
This object is simpler. It holds the plotGUI in a property, allowing direct access to the plotGUI properties and public methods.
properties (Access = public)
PlotWindow = plotGUI() % holds the reference to the plot window
end
I also created an updatePlot callback method here, different from the plotGUI method, bad naming on my part. Nonetheless, this control method takes the values from controlGUI dropdowns and then modifies the plotGUI DATA struct, stored in app.PlotWindow.DATA. So this one callback is called whenever any of the dropdowns are changed (ValueChangedFcn). Consequently, the PostSet listener for the DATA struct will fire the callback to update the plot accordingly.
% Value changed function: LineColor, LineStyle, MarkerStyle
function updatePlot(app, event)
mStyle= app.MarkerStyle.Value;
lStyle= app.LineStyle.Value;
lColor = app.LineColor.Value;
d = app.PlotWindow.DATA;
switch mStyle
case 'none'
d.marker = 'none';
case 'circle'
d.marker = 'o';
case 'diamond'
d.marker = 'diamond';
case 'point'
d.marker = '.';
end
switch lStyle
case 'none'
d.linestyle = 'none';
case 'solid'
d.linestyle = '-';
case 'dashed'
d.linestyle = '--';
case 'dotted'
d.linestyle = ':';
end
d.color = lColor;
% set the data back into the plotGUI
% The plotGUI's DATA PostSet listener will update the actual plot
app.PlotWindow.DATA = d;
end
You aren't supposed to copy/paste the code outside of the code editor with App Designer. If you want to add your own code, you should add a new function to your class using the "Function" button in App Designer. The app can also call any other matlab function so you could just pass the information from the app to another function by calling it inside the App Designer code
For example see this example from a demo I created. It uses a drop down ChartTypeDropDown to determine what type of chart it should draw. I added a new function called DrawChart which uses the data from the GUI to draw a graph depending on the values selected/entered in to the various boxes.
function results = DrawChart(app)
chartType = app.ChartTypeDropDown.Value;
chartTime = app.TimeEditField.Value;
chartA = app.AEditField.Value;
chartB = app.BEditField.Value;
chartC = app.CEditField.Value;
t = [0:0.1:chartTime];
if strcmp(chartType,'Sin')
y = chartA * sin(chartB*t)+chartC;
elseif strcmp(chartType,'Cos')
y = chartA * cos(chartB*t)+chartC;
elseif strcmp(chartType,'Exp')
y = exp(t);
else
y = x;
end
ax = app.UIAxes;
ax.Title.String = chartType;
plot(ax,t,y);
end
This function is called by the callback linked to a button
function DrawButtonPushed(app, event)
DrawChart(app);
end
Note how I call regular matlab functions such as sin/cos/exp. These could just as easily be a Matlab function that you have written.
On MATLAB R2014b, when you have a struct (or custom class) having a field that is a scalar categorical, when displaying the struct it will show [1x1 categorical] instead of what I want to achieve as shown below.
MWE:
struct.field = categorical({'category'})
Output:
struct =
field: [1x1 categorical]
My desired output:
struct =
field: category
or:
struct =
field: category [1x1 categorical]
I want this, because I'm writing some classes that have a categorical property that is always scalar; because I know this by definition, I don't need the objects' category to be displayed as [1x1 categorical]. When displaying the custom objects, I'd like it to show the category instead.
I could overload disp in my class methods, but then I'd need to rewrite a lot of displaying code from disp itself instead of merely changing the way a scalar categorical in a struct field shows.
Any ideas on how to achieve this? If your answer involves overloading disp in the class definition, then I want to see how you could display the object's other properties like a normal disp(obj) would, in addition to displaying the categorical property the way I want. Any ideas or thoughts you have might help me write my own answer, so please share any.
After playing around with this for a while, I think I finally have something that works for displaying these scalar categorical values within a custom class.
The basic idea is that I overload the get method for the property that is holding the categorical. I can then check the call stack to see what is trying to get the value of the variable. If it's our overloaded disp method (which is called any time we want to display our class), then I return the category name if it's only a scalar categorical. Otherwise, I return the value of the property itself (as a categorical).
It's definitely not the most elegant due to it's reliance on dbstack but it seems to work quite well.
classdef categoryclass < handle
properties
a = categorical({'category'});
end
methods
% Get Method for "a" property
function res = get.a(self)
% Get the call stack to determine *what* called this
stack = dbstack();
methodname = sprintf('%s.disp', class(self));
% If it is a scalar and it was called by our overloaded display
% method, then return the category name
if isscalar(self.a) && isa(self.a, 'categorical') && ...
strcmp(methodname, stack(end).name)
res = categories(self.a);
res = res{1};
% Otherwise return just the value itself
else
res = self.a;
end
end
% This ensure that disp() shows up in the stack
function disp(self)
% Simply call the built-in display function
builtin('disp', self);
end
end
end
Now if we try this out.
cls = categoryclass()
categoryclass with properties:
a: 'category'
Check that when we request the value we actually get a categorical.
class(cls.a)
ans =
categorical
Now change the value of it.
cls.a = categorical({'another category'})
categoryclass with properties:
a: 'another category'
Now use two categories
cls.a = categorical({'one', 'two'})
categoryclass with properties:
a: [1x2 categorical]
NOTE: This only appears to be an issue in R2014b and R2015a. It was fixed in all later releases.
It's been a while, but today I needed this again. I thought of another way to display scalar categorical variables. The following example class does the trick.
classdef dispfmtTest < matlab.mixin.Copyable
properties
prop = categorical(1) % default value is a scalar categorical
end
methods
function dispfmt(obj) % dispfmtTest object to display format
obj.prop = char(obj.prop); % convert to char type
end
function disp(self)
obj = copy(self); % copy is provided by superclass
dispfmt(obj)
disp#matlab.mixin.Copyable(obj) % call superclass disp
delete(obj)
end
end
end
The dispfmtTest class is a subclass of matlab.mixin.Copyable, which is in turn a subclass of handle. It provides the copy method to the disfmtTest class, which is used to temporarily create a copy of which the value of property prop is changed to whatever desired display format in method dispfmt. Then, the modified copy of the object is displayed using the regular disp function as provided by matlab.mixin.Copyable.
Demo
Running obj = dispfmtTest yields
d =
dispfmtTest with properties:
prop: '1'
and class(d.prop) yields
ans =
categorical
This is the behaviour as I expected. Support for array properties can be achieved too using isscalar.
We have this code in 'Reconstruction the subclass object from a saved struct' from MATLAB OOP documentation.
classdef MySuper
% Superclass definition
properties
X
Y
end
methods
function S = saveobj(obj)
% Save property values in struct
% Return struct for save function to write to MAT-file
S.PointX = obj.X;
S.PointY = obj.Y;
end
function obj = reload(obj,S)
% Method used to assign values from struct to properties
% Called by loadobj and subclass
obj.X = S.PointX;
obj.Y = S.PointY;
end
end
methods (Static)
function obj = loadobj(S)
% Constructs a MySuper object
% loadobj used when a superclass object is saved directly
% Calls reload to assign property values retrived from struct
% loadobj must be Static so it can be called without object
obj = MySuper;
obj = reload(obj,S);
end
end
end
I have a question about obj = MySuper. What is purpose of this line? How we can call MySuper object from this function without insert any object to loadobj function?
You first question is: What is the purpose of the obj = MySuper; line?
The answer is that the obj = MySuper; line initiates the variable obj as an element of the class MySuper. Non-static functions in a class will only run if the first input parameter is an instance of the class, so if obj is not initiated as a MySuper-object, then matlab will look for other functions called reload to run, and if none is found give you an error.
For your second question, I am not 100% sure what you mean. But I hope one of the following points will answer your question:
If you want to make a function that relates to a class, but not to a specific instance of the class, you can make a static function, these can take any input (also (if you want it that way) no input at all) - that is they don't need to have a first input parameter of the specific class.
To run a static function, use the class name followed by a dot and then the function name, so here you would type MySuper.loadobj(S) to run the function with the parameter S.
I would suggest that you try this out with the given example to better get to know the way oop works in matlab, you may for example try:
S.PointX = 1;
S.PointY = 2;
obj = MySuper.loadobj(S)
I hope this answers your questions.
I come from a Java background. I am having issues with classes in Matlab particularly getters and setters. getting a message saying conflict between handle and value class I'm a little lost with what to do so any help for lack of a better word will be helpful.
classdef Person
properties(Access = private)
name;
age;
end
methods
% class constructor
function obj = Person(age,name)
obj.age = age;
obj.name = name;
end
%getters
function name = get.name(obj)
end
function age = get.age(obj)
end
%setters
function value = set.name(obj,name)
end
function value = set.age(obj,age)
end
end
end
Implementation
Since your class is currently a subclass of the default Value class, your setters need to return the modified object:
function obj = set.name(obj,name)
end
function obj = set.age(obj,age)
end
From the documention: "If you pass [a value class] to a function, the function must return the modified object." And in particular: "In value classes, methods ... that modify the object must return a modified object to copy over the existing object variable".
Handle classes (classdef Person < handle) do not need to return the modified object (like returning void):
function [] = set.name(obj,name)
end
function [] = set.age(obj,age)
end
Value vs. Handle
Going a bit deeper, the difference between a Value class and a Handle class lies mostly in assignment:
Assigning a Value class instance to a variable creates a copy of that class.
Assigning a Handle class instance to a variable create a reference (alias) to that instance.
The Mathworks has a good rundown on this topic.
To paraphrase their illustration, the behavior of a Value class is
% p is an instance of Polynomial
p = Polynomial();
% p2 is also an instance of Polynomial with p's state at assignment
p2 = p;
and of a Handle class is
% db is an instance of Database
db = Database();
% db2 is a reference to the db instance
db2 = db;
Quick'n Dirty from the Java perspective:
- "handle" classes are what your mind is set to. proper object instances with pointers to them. use them.
- "value" classes are always returning a full clone of whatever object (which has been modified by what you just did, e.g. setting a name).
the reason they have both in Matlab is that in Matlab you would expect the "value" behaviour natively. Imagine you have a matrix A = [1 2; 3 4], then assign that via B = A. if you now set B(1) = -1 you'd hope that A(1) is still 1, right? this is because matlab keeps track of "copies" and truly creates them as you modify different variables initially set to the same matrix. in OOP you'd have A(1)=-1 now as everythings an object reference.
furthermore, "native" matlab routines dont have a "this/self/me" variable that contains the instance reference to access from within functions. instead, the convention is that the class instance will be prepended to the function's argument list.
so for a function call myclass.mymethod(arg1,arg1), the declaration must be
function mymethod(this, arg1, arg2)
% Note that the name you choose for "this" is arbitrary!
end
mind you, this is the java-perspective (and also my favourite one), the above function call is equivalent to mymethod(myclass,arg1,arg1). this is more native to matlab-style, but somehow makes it harder to see you're calling an objects method.
now, regarding setters/getters: for handle classes, everything feels java-ish now:
classdef MyClass < handle
properties
MyProp;
end
methods
function set.MyProp(this, value) %Note: setMyProp is also valid!
... % do checks etc, trigger calls,
this.MyProp = value;
end
function value = get.MyProp(this)
... % notify, update, triggers etc
value = this.MyProp;
end
end
Of course it goes without saying that you dont need to define a getter if you just want to return the value, i.e. myclassinstance.MyProp will work without any just as well.
Finally, getters/setters for value classes are something that [never encountered me/i never needed] in my 7 years of matlab oop, so my advise would be to go with handle classes and enjoy happy matlab coding :-)
otherwise, the above explanation & official matlab docs is doing the job for value class getter/setters.
Writing a subclass of dynamicprops allows to me to add properties dynamically to an object:
addprop(obj, 'new_prop')
This is great, but I would also love to create set / get functions for these properties on the fly. Or analysis functions that work on these dynamic properties.
My experience with Matlab has been so far, that once I create an instance of a class, adding new methods is not possible. That is very cumbersome, because my object may contain a lot of data, which I'll have to re-load every time that I want to add a new method (because I have to do clear classes).
So is there a way to add methods on the fly?
You cannot add methods like you add dynamic properties. However, there are two ways for implementing new methods during development that won't require you to re-load the data every time.
(1) I write standard methods as separate functions, and call them as myMethod(obj) during development. Once I'm sure they're stable, I add their signature into the class definition file - this requires a clear classes, of course, but it is a much delayed one, and from time to time you may have to shut down Matlab, anyway.
(2) With set/get methods, things are a little trickier. If you are using dynamicprops to add new properties, you can also specify their set/get methods, however (most likely, these methods/functions will want to receive the name of the property so that they know what to refer to):
addprop(obj,'new_prop');
prop = findprop(obj,'new_prop');
prop.SetMethod = #(obj,val)yourCustomSetMethod(obj,val,'new_prop')
EDIT
(2.1) Here's an example of how to set up a hidden property to store and retrieve results (based on jmlopez' answer). Obviously this can be improved a lot if you have a better idea what you're actually designing
classdef myDynamicClass < dynamicprops
properties (Hidden)
name %# class name
store %# structure that stores the values of the dynamic properties
end
methods
function self = myDynamicClass(clsname, varargin)
% self = myDynamicClass(clsname, propname, type)
% here type is a handle to a basic datatype.
self.name_ = clsname;
for i=1:2:length(varargin)
key = varargin{i};
addprop(self, key);
prop = findprop(self, key);
prop.SetMethod = #(obj,val)myDynamicClass.setMethod(obj,val,key);
prop.GetMethod = #(obj)myDynamicClass.getMethod(obj,key);
end
end
function out = classname(self)
out = self.name_;
end
end
methods (Static, Hidden) %# you may want to put these in a separate fcn instead
function setMethod(self,val,key)
%# have a generic test, for example, force nonempty double
validateattributes(val,{'double'},{'nonempty'}); %# will error if not double or if empty
%# store
self.store.(key) = val;
end
function val = getMethod(self,key)
%# check whether the property exists already, return NaN otherwise
%# could also use this to load from file if the data is not supposed to be loaded on construction
if isfield(self.store,key)
val = self.store.(key);
else
val = NaN;
end
end
end
end
I'm adding this answer because I think that this is not intuitive. At least not to myself at this moment. After finding this question I thought I had what I needed to be able to define the set/get methods for my dynamic class. All I wanted to achieve with this was something similar to what python does with its __setattr__ method. In any case, here is a continuation of the class made by #jonas a while ago with a few modifications to add the our custom set method.
classdef myDynamicClass < dynamicprops
properties (Hidden)
name_ %# class name
end
methods
function self = myDynamicClass(clsname, varargin)
% self = myDynamicClass(clsname, propname, type)
% here type is a handle to a basic datatype.
self.name_ = clsname;
for i=1:2:length(varargin)
key = varargin{i};
addprop(self, key);
prop = findprop(self, key);
prop.SetMethod = makefunc(key, varargin{i+1});
end
end
function out = classname(self)
out = self.name_;
end
end
end
function h = makefunc(key, argtype)
h = #newfunc;
function newfunc(obj, val)
obj.(key) = argtype(val);
end
end
With this class I'm defining the set method so that the parameter passed to the attribute is copied to the right type. To see what I mean consider the following usage:
>> p_int = myDynamicClass('Point', 'x', #int8, 'y', #int32);
>> p_int.x = 1000
p_int =
myDynamicClass with properties:
y: []
x: 127
>> class(p_int.x)
ans =
int8
With this we have forced the x attribute to be an integer of 8 bits which can only hold integers from -128 to 127. Also notice how the class of each attribute gives us the intended type.
My experience with Matlab has been so far, that once I create an instance of a class, adding new methods is not possible. That is very cumbersome, because my object may contain a lot of data, which I'll have to re-load everytime that I want to add a new method (because I have to do clear classes).
It's worth noting for present-day readers of this question that this is no longer true. As of MATLAB R2014b MATLAB updates class definitions at the moment you save them, and the behaviour of existing class instances automatically updates accordingly. In the case of adding new methods, this is uncomplicated: the new method simply becomes available to call on class instances even if they were created before the method was added to the class.
The solutions given for choosing set/get methods for dynamic properties still apply.
There are still cases where you might want to add methods to an instance dynamically and the method doesn't constitute a property set/get method. I think the only answer in this case is to assign a function handle as the value to a dynamic property. This doesn't create a bona fide method, but will allow you to call it in the same way you would a method call:
addprop(obj, 'new_method');
obj.new_method = #(varargin) my_method(obj,varargin{:});
Calls to obj.new_method(args) are thus passed to my_method; however this only works with a scalar obj; an array of instances will have separate values for the new_method property so obj.new_method no longer resolves to a single function handle that can be called if obj is an array.