matlabhandlematlab-class

How to create a "one-way dependency" within Matlab handle class


I am fairly new to Matlab, and I was wondering if there is a way to create a "one-way handle class".

To explain better, lets say I have a class called test_class, with properties "prop1" and "prop2"

test_1 = test_class(5,10)
test_2 = test_1

I wanted changes applied to properties within test_1 (parent) to affect test_2 (child), but I do not want changes in test_2 to affect test_1, so

test_1.prop1 = 20;
test_2.prop1: 20

test_2.prop2 = 30;
test_1.prop2: 5

Is there a way to create such a "one-way dependecy"?

Thanks in advance!


Solution

  • You can do this without getting into the difficulties of subasgn by leveraging property set listeners. This way you don't need ot get in the business of holding on to and managing all of the children copies. This looks something like the following:

    classdef test_class < matlab.mixin.Copyable
    
        properties(SetObservable)
            prop1
            prop2
        end
    
        properties
            prop3
        end
    
        methods
            function obj = test_class(in1, in2, in3)
                obj.prop1 = in1;
                obj.prop2 = in2;
                obj.prop3 = in3;
            end
            function ref = make_dependent_reference(obj)
                ref = copy(obj);
    
                cls = metaclass(obj);
                observableProps = cls.PropertyList.findobj('SetObservable',true);
                for ct =1:numel(observableProps)
                    obj.addlistener(observableProps(ct).Name, 'PostSet', ...
                        @(prop,evd)ref.update_dependent_reference(prop,evd));
                end
            end
        end
        methods(Access=private)
            function update_dependent_reference(ref, prop, evd)
                ref.(prop.Name) = evd.AffectedObject.(prop.Name);
            end
        end
    end
    

    Note, this requires the properties to be SetObservable, you can either choose to make the reference updates to those properties ignore properties that are not SetObservable like I've shown above with the findobj call or you can instead operate on all properties and let the addlistener call error out for any properties that are not SetObservable.

    >> t = test_class(5,10,15)
    
    t = 
    
      test_class with properties:
    
        prop1: 5
        prop2: 10
        prop3: 15
    
    >> ref = t.make_dependent_reference
    
    ref = 
    
      test_class with properties:
    
        prop1: 5
        prop2: 10
        prop3: 15
    
    >> ref.prop1 = 6
    
    ref = 
    
      test_class with properties:
    
        prop1: 6
        prop2: 10
        prop3: 15
    
    >> t
    
    t = 
    
      test_class with properties:
    
        prop1: 5
        prop2: 10
        prop3: 15
    
    >> t.prop2 = 11
    
    t = 
    
      test_class with properties:
    
        prop1: 5
        prop2: 11
        prop3: 15
    
    >> ref
    
    ref = 
    
      test_class with properties:
    
        prop1: 6
        prop2: 11
        prop3: 15