Search code examples
matlabclassoopdynamic-properties

Is it possible to add methods on the fly to MATLAB classes?


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?


Solution

  • 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