2

In Matlab, I would like to perform some operations on private members of a class. I would also like to perform this exact same task on other classes as well. The obvious solution is to write a function in a separate M file that all the classes call in order to perform this task. However, that seems impossible in Matlab (see below). Is there another way to accomplish this?

Here is the problem specifically: suppose I have one m file with the contents

classdef PrivateTest
    properties (Access=private)
        a
    end

    methods
        function this = directWrite(this, v)
            this.a = v;
        end
        function this = sameFileWrite(this, v)
            this = writePrivate(this, v);
        end
        function this = otherFileWrite(this, v)
            this = otherFileWritePrivate(this, v);
        end
        function print(this)
            disp(this.a);
        end
    end
end

function this = writePrivate(this, v)
    this.a = v;
end

...and another m file with the contents

function this = otherFileWritePrivate(this, v)
    this.a = v;
end

After instantiating p = PrivateTest, both of these commands work fine (as expected):

p = p.directWrite(1);
p = p.sameFileWrite(2);

...but this command doesn't work even though it's the same code, just in a different m file:

p = p.otherFileWrite(3);

So, it seems like any code that performs operations on private properties of a class MUST be in the same m file as the classdef that defines those private properties. Another possibility might be to have all the classes inherit a class with the writing method, but Matlab doesn't allow this either. In one m file, I would have this code:

classdef WriteableA
    methods
        function this = inheritWrite(this, v)
            this.a = v;
        end
    end
end

...and in another m file I would have this code:

classdef PrivateTestInherit < WriteableA
    properties (Access=private)
        a
    end
end

However, after instantiating p = PrivateTestInherit;, the command p.inheritWrite(4) causes the same error message as before: "Setting the 'a' property of the 'PrivateTestInherit' class is not allowed."

In light of this, How is it possible to generalize code that manipulates private properties in Matlab, or is it possible?

Ben
  • 1,272
  • 13
  • 28

1 Answers1

0

It is not possible to manipulate private properties outside of the class, that is why they are called private. This idea is called encapsulation.

You can in solve it in many ways:

  1. Define public property that wraps the private, and change it. (See code below)
  2. (Inheritance pattern) Do a common father class, your other classes inherit the function

classdef PrivateTest
    properties (Access=private)
        a
    end

    properties(Access=public,Dependent)
        A
    end

    methods
        function this = set.A(this,val)
            this.a = val;
        end

        function val = get.A(this)
           val = this.a;
        end

        function this = directWrite(this, v)
            this.a = v;
        end
        function this = sameFileWrite(this, v)
            this = writePrivate(this, v);
        end
        function this = otherFileWrite(this, v)
            this = otherFileWritePrivate(this, v);
        end
        function print(this)
            disp(this.a);
        end
    end
end

function this = writePrivate(this, v)
    this.A = v;
end
Andrey Rubshtein
  • 20,795
  • 11
  • 69
  • 104
  • Sorry, my method naming was confusing. The otherFileWritePrivate function is the only function defined in an m file named 'otherFileWritePrivate.m'. The error message generated from `p = p.otherFileWrite(3);` is "Setting the 'a' property of the 'PrivateTest' class is not allowed.", not "Undefined function 'otherFileWritePrivate' for input arguments of type 'PrivateTest'." – Ben Oct 10 '12 at 19:39
  • [Above comment no longer applies] I'm not trying to manipulate private properties outside the class; it is PrivateTest's method which is calling the external m file. The exact same code works fine when it's in the same m file, it just doesn't work when I try to follow good coding practice by generalizing it by putting it in a separate m file where multiple classes can use the same code. I want to maintain encapsulation so option 1 is no good. I'm pretty sure option 2 is impossible in Matlab also, but I'll update the question to include what I've tried. – Ben Oct 10 '12 at 19:47
  • @Ben, I think you do. You are doing `this.a = v;` in `otherFileWritePrivate.m`. From Matlab point of view, you called external function, passed the object to it, so it can change only its public properties – Andrey Rubshtein Oct 10 '12 at 19:50
  • sure, that's the underlying question -- since Matlab appears to consider code in different m files as external to classes even if that code is called from within the classes, how can one write generalized code to manipulate private properties? – Ben Oct 10 '12 at 19:57
  • The code in this answer with A as a public dependent property is just changing my private property into a public one. It doesn't allow generalization of manipulation of private properties. – Ben Oct 10 '12 at 19:57
  • This is the way I really want to solve this problem (C# code), but I don't think will work in Matlab (see question 12830716): public static void setA(Object p, double v) { Type t = p.GetType(); FieldInfo fi = null; while (fi == null) { fi = t.GetField("a", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); t = t.BaseType; } fi.SetValue(p, v); } – Ben Dec 19 '12 at 21:35