Rico Picone
Rico Picone

Reputation: 401

Matlab method as a property

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

Answers (3)

Rico Picone
Rico Picone

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

Cris Luengo
Cris Luengo

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

Alex Taylor
Alex Taylor

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

Related Questions