Reputation: 401
Is there a way to write a Matlab class that has one of its own methods as a property? I'm writing simulation code in which the class's method (which is effectively a physics equation) might change in future development, so I'd like archived class instances to include the method.
Here's some Matlab-ish pseudocode.
classdef foo
properties
bar % some property
baz % a property that contains the method baz
end
methods
function out = baz() % the method I want to store
stuff
end
end
end
Note that I want "stuff" to be somehow stored as a property so when I save an instance, I will know the version of the method I used.
It is preferable that it is public and also not a static property. I'd like to serialize instances.
Upvotes: 2
Views: 159
Reputation: 401
Based on Dev-iL's comment and Cris's answer, here's what I did, which stores the entire classdef
file as plain text in the property class_definition
.
classdef foo
properties
class_definition
end
methods
function obj = foo()
obj.class_definition = fileread([mfilename(),'.m']);
end
function out = baz() % the method I want to store
stuff
end
end
end
As Dev-iL suggests, writing a function that accepts a filename and function/method handle and returns that function's code (as opposed to the entire classdef
file) as plain text would probably better answer the original question, so I'll accept such an answer if it's posted. This solution was sufficient for my purposes.
Upvotes: 1
Reputation: 60444
If your function is a single expression, you can use an anonymous function. It will be saved to a MAT-file (Thanks to gnovice for pointing this out). So for example:
classdef foo
properties
bar = 0
baz = @(x)sqrt(x)
end
end
Now I can do:
f = foo;
f.baz(2) % returns 1.4142
save foo_test f
clear
And then change the definition of baz
in foo.m
to baz = @(x)x.^2
, and then:
f2 = foo;
f2.baz(2) % returns 4
load foo_test
f.baz(2) % still returns 1.4142
f2.baz(2) % still returns 4
If you have more complex functions you could set it up this way:
classdef foo
properties
bar = 5
baz_func = @(obj,x) baz_2019_05_22(obj,x) % could be private
end
methods
function out = baz(obj,x)
out = obj.baz_func(obj,x);
end
function out = baz_2019_05_22(obj,x) % could be private
out = obj.bar * sqrt(x);
end
end
end
And now:
f = foo;
f.baz(2) % returns 7.0711
save foo_test f
clear
In the future you'd change the function, but you preserve the code and create a new (private) function that does the computation:
classdef foo
properties
bar = 5
baz_func = @(obj,x) baz_2022_08_04(obj,x) % could be private
end
methods
function out = baz(obj,x)
out = obj.baz_func(obj,x);
end
function out = baz_2019_05_22(obj,x) % could be private
out = obj.bar * sqrt(x);
end
function out = baz_2022_08_04(obj,x) % could be private
out = obj.bar * x.^2;
end
end
end
The difficulty here is to preserve the old code without changing it... But you can make the baz
function as complex as you want here. Now:
f2 = foo;
f2.baz(2) % returns 20
load foo_test
f.baz(2) % still returns 7.0711
Upvotes: 3
Reputation: 1412
classdef foo
properties (Dependent, SetAccess = 'private')
baz % a property that contains the method baz
end
methods
function out = bazMethod() % the method I want to store
stuff
end
function bazOut = get.baz(self)
bazOut = bazMethod();
end
end
end
It won't serialize the current method definition bazMethod, but if what you want is simply the definition, it kind of sounds like what you want is for baz to be a Dependent property.
Upvotes: 1