Search code examples
matlaboopcell-arrayprivate-methodsobject-properties

Class instance variable does not retain changes when method is called


I created a class in MATLAB:

classdef Compiler
%UNTITLED2 Summary of this class goes here
%   Detailed explanation goes here

properties(Access = public)
    in=''       %a line of string of MATLAB code
    out={}      %several lines of string(cell array) of Babbage Code
end

methods(Access = private)
    %compile(compiler);
    expression(compiler); 
    term(compiler);
end

methods(Access = public)
    function compiler = Compiler(str) 
        compiler.in = str;
        expression(compiler);
        compiler.out
    end
end

And I have expression function as:

function expression(compiler)
%Compile(Parse and Generate Babbage code)one line of MATLAB code

   term(compiler);         
end

and the term function as:

function term(compiler)
    % Read Number/Variable terms
    num = regexp(compiler.in, '[0-9]+','match');
    len = length(compiler.out);
    compiler.out(len+1,:) = {['Number ' num{1} ' in V0 in Store']}; 
    compiler.out(len+2,:) = {['Number ' num{2} ' in V1 in Store']};
end

When I tried to run Compiler('3+1'), the output is empty. I tried to debug it step by step and I found that when the term function finished and jumped back to the expression function, the compiler.out changed from a 2 x 1 cell arrays to empty.

I am confused about that. I have implemented other classes similar to this and all of their properties could be changed by my class's private function.


Solution

  • When you are making changes to an instance of your class, if you wish the changes to be registered, you must inherit from the handle class. If you don't do this, any changes made to the instance of your class are assumed to be returned and you must have an output variable that reflects this.

    Therefore at the top of your class definition, inherit from the handle class:

    classdef Compiler < handle
    

    Also, your class definition isn't quite correct. You need to ensure that expression and term are fully defined within the methods block that is private. You're also missing one final end at the end of your class definition and finally, you don't need to echo compiler.out in the constructor:

    classdef Compiler < handle %%%% CHANGE
    %UNTITLED2 Summary of this class goes here
    %   Detailed explanation goes here
    
    properties(Access = public)
        in=''       %a line of string of MATLAB code
        out={}      %several lines of string(cell array) of Babbage Code
    end
    
    methods(Access = private)
        %%%% CHANGE
        function expression(compiler)
        %Compile(Parse and Generate Babbage code)one line of MATLAB code
           term(compiler);         
        end
    
        %%%% CHANGE
        function term(compiler)
            % Read Number/Variable terms
            num = regexp(compiler.in, '[0-9]+','match');
            len = length(compiler.out);
            compiler.out(len+1,:) = {['Number ' num{1} ' in V0 in Store']}; 
            compiler.out(len+2,:) = {['Number ' num{2} ' in V1 in Store']};
        end 
    end
    
    methods(Access = public)
        function compiler = Compiler(str) 
            compiler.in = str;
            expression(compiler);
            %compiler.out % don't need this
        end     
    end
    
    end
    

    Now, when I do Compiler(3+1), I get:

    >> Compiler('3+1')
    
    ans = 
    
      Compiler with properties:
    
         in: '3+1'
        out: {2x1 cell}
    

    The variable out now contains the strings you are seeking:

    >> celldisp(ans.out)
    
    ans{1} =
    
    Number 3 in V0 in Store
    
    
    ans{2} =
    
    Number 1 in V1 in Store