1

I am calling a function to change parameters of my class inside its constructor, however, I can't change the values. Is this a bug or on purpose?

In the following example, I am calling function "calculateCalculatedProperties()" inside constructor. "calculateCalculatedProperties()" calls "Velocity()" and "Length()" function which sets new values of velocity and length properties. However, at the end product of the constructor (object instance) properties are unchanged.

classdef piping
    %PIPING Summary of this class goes here
    %   Detailed explanation goes here
    
    properties 
        flowRate
        diameter
        startLocation location
        endLocation location
    end

    
    
    methods
        function self = piping(flowRate, diameter, startLocation, endLocation)
            
            self.flowRate = flowRate;
            self.diameter = diameter;
            self.startLocation = startLocation;
            self.endLocation = endLocation;
            
            self.calculateCalculatedProperties();
                       
        end
        
        function self = calculateCalculatedProperties(self)
            fprintf("hey")
            self.Velocity();
            self.Length();
        end
        
        
         function self = Velocity(self)
             self.velocity = self.flowRate / (pi * self.diameter^2 / 4);
         end
        
         function self = Length(self)
            self.length = location.calculateDistance(self.startLocation,self.endLocation) ;
            fprintf("hey this is lengthhhh")
            self.flowRate = 10000000;
         end

        
    end
    
    properties % Calculated properties
        
        velocity
        length
    end
end

RedGermen
  • 13
  • 3

1 Answers1

1

The issue here is that you are using a value class, not a handle class. Note that in your Velocity method you are returning an instance of "self", in a value class these method invocations return a separate object, which is being ignored in this code.

That being said two possible solutions:

  1. Capture output of value objects and return the final, modified object.

     function self = piping(flowRate, diameter, startLocation, endLocation)
         % ...
         self = self.calculateCalculatedProperties();      
     end
    
     function self = calculateCalculatedProperties(self)
         fprintf("hey")
         self = self.Velocity();
         self = self.Length();
     end
    
  2. Use handle classes to create a mutable object.

     classdef piping < handle
         % ...
     end
    

See Comparison of Handle and Value Classes for more info.

GleasonK
  • 1,032
  • 8
  • 17
  • Thank you! Now everything works! But I have another question, why would I want to keep my class as a value class? – RedGermen Oct 30 '20 at 19:23
  • 1
    That's a long discussion, but in brief: Value classes let you program in a safe, low-side-effect "functional programming" style: they avoid "aliasing" of object references which results in shared mutable state and possible unintended side effects, and they let you modify multiple fields on an object in an atomic, "transactional" manner. Plus most Matlab things are value and not handle/reference things, so value objects play better with them. My rule of thumb is that in Matlab, you should avoid handle classes unless you have a specific need for them. – Andrew Janke Nov 02 '20 at 05:36
  • 2
    (The main reason to need a handle object is if that object wraps or contains things which are themselves handle-like pass-by-reference things, such as Matlab handle graphics handles, filehandles, other Matlab handle objects, Java object references, or other things that reference the state of external shared resources, such as filesystem objects or database connections.) – Andrew Janke Nov 02 '20 at 05:40