Matlab class with knowledge of instance name in the constructor - matlab

I would like to have a class which, in its constructor, can have knowledge (extract as a string) its instance name.
For the moment I worked the name extraction out like this:
classdef mysession
methods (Access = public)
function this=mysession (varargin)
this.cargs=varargin;
this.built=false;
end
function id=build(this)
id=this.mynameis;
this.id = id;
%% instructions needing id
built=true;
end
function name = mynameis (this)
name=evalin ('caller', 'inputname');
end
end
properties (Access=private)
id
built
cargs
end
end
which requires the ugly
A = mysession; A.build
syntax in order to work...

There is no way to get the variable name that is used to assign the output of a function or class constructor. As you've discovered, the only way to get the object's variable name in the calling workspace is to call another method of the class at which point you can use inputname to query it.
That aside, it's not clear why you need to do this but I'd strongly discourage it. Particularly with handle classes, you can have multiple variables point to the same object, therefore the object technically has multiple names.

Related

Organizing similar class and instance methods within a class

I have a class, for which I have static methods that calculate something (example below in MATLAB, since that's what I'm using, although I think my question may be more general):
methods (Static)
function out = f(x)
out = x*2;
end
end
Suppose I have instance methods where I want to do the same calculation (and hence use the aforementioned class method), but I also want to do something specific to the class, like updating a property or maybe passing in an instance property into the calculation. So like:
methods
function out = f(this)
out = ClassName.f(this.x); % Use the class method, but pass in an instance variable
end
% OR
function [this, out] = f(this,x)
out = ClassName.f(x)*2; % Use the class method with a provided input
this.value = out; % then assign value to an instance variable
end
end
At least in MATLAB, I can't overload a class method with an instance method (I can overload a built-in MATLAB method within my class, but that's not what I want here), so I'm not sure how to go about this in a proper OOP way. I want to keep the class method there in case someone wants to use the specific calculation on some data they collected outside the class, but I also want the instance method in case someone decides to use the class to collect data and then analyze the data with the built methods.

Matlab alter attribute value by method

I tried to change an attribute value of a class by invoking one of its member function:
p1 = tank();
p1.checkOri(p1);
And in the class definition, I have that static method:
classdef tank
properties
value
...
end
methods
...
methods (Static)
function obj = checkOri(obj)
if (CONDITION) %the thing I want it to do
obj.value = EXPRESSION;
...
Yet this checkOri method is not working. But if I write this method in the main file, or to say altering the value of p1-the instance of class tank-it works perfectly:
p1 = tank();
p1.checkOri(p1);
if (CONDITION) %the thing I want it to do
p1.value = EXPRESSION;
It works perfectly.
I wonder what caused this. From my experience with other programming languages, invoking method should have worked, is it because of some tricks with Matlab syntax or static method? How could I fix it so that this method would work?
So, as #Navan in the comment said, handle class could be a solution.
It appears Matlab has a similar parameter concept with Java and C++, arguments modified in a function/method only remains that modification inside the function/method.
For this class, I simply added < handle in the head of class definition and it worked:
classdef tank < handle
properties
...
But I am not sure if that is the only solution, there might be better ways to do this. So I'll leave that question open, you are more than welcomed to post your opinion:D
In MATLAB, the call
p1.checkOri();
is equivalent to
checkOri(p1);
In both cases, the class method checkOri is called for the class of object p1, passing p1 as first argument to the function by value.
Because p1 is passed by value, any changes made to it inside the function are not seen by the object in the calling workspace. Therefore, one typically does
p1 = checkOri(p1);
This way, the object that was passed by value and modified inside the function is passed back out and assigned to the variable that held the original object.
If the method is written as follows:
function obj = checkOri(obj)
%...
end
then MATLAB will optimize the above function call such that no copy of the object is actually made. Note that both in the function declaration and in the function call, the input and output variable is the same.
As already discovered by OP, the above does not hold for handle classes, classes that inherit from handle. These classes act as if they are always passed by reference, and any change made to them in any workspace will be reflected in all other copies in other workspaces.
Also assigning to a member variable does not follow the above, such that
p1.value = 0;
modifies object p1.
For more information on the difference between value classes and handle classes see this other question.

Load or import map for use by class instance in matlab

I have a containers.Map file/variable that I've defined through the Matlab Command Window (or some other script) and have saved it to directory. I'd like to be able to have an instance of my class be able to use that map without having to define it in the class definition, or with some other function that defines it each time the function is called. So I have:
myMap.mat
and in a separate myClass.m file (in the same directory) i'd like to be able to call myMap like so:
classdef myClass < handle
properties
number
end
methods
function obj = myClass(input)
obj.number = myMap(input);
end
end
end
What's the most efficient way to get myMap "into the class" so that the instance can use it? matfile has been giving me some Warnings about format not supporting partial loading, and I can't imagine load is terribly efficient. Any suggestions is appreciated.
There are many approaches you can use but, honestly, I think the simplest one would be using a persistent object in your class constructor, as follows:
classdef myClass < handle
properties
number
end
methods
function obj = myClass(input)
persistent pmap;
if (isempty(pmap))
load('map.mat','map');
pmap = map;
end
obj.number = pmap(input);
end
end
end

What is the difference between calling a dependent property of a class with and without parentheses?

Say I have a class like such:
classdef exampleClass
properties (Dependent=true)
x
end
methods
function this=exampleClass(this)
this.x = 4;
end
function x=get.x(this)
x=4;
end
end
end
What's the difference in accessing x as classInstance.x and classInstance.x()?
The function get.x(this) is called a getter of the property x. It actually has nothing to do whether the property has the attribute Dependent or not, it is the same for any type of property.
If you have a setter/getter defined for your property, Matlab will always call the function get.PropertyName or set.PropertyName when you do something like:
tmp_var = my_instance.x
or
my_instance.x = 3.1416;
So if you have in your code my_instance.x or my_instance.x() is practically the same. But if you want to follow best practices, you must avoid the function call.
Now, as an extra point: for performance reasons, it is recommended that you do not use setters/getters because every time you modify your property (even inside your class) you will pay the price of the overhead of the setter/getter.

Matlab Class Method Error

I'm new to matlab classes and have just gone through a couple tutorials and now am trying to make one. In my methods section however, I'm having trouble with what I've been trying to do. The object should only need a single piece of info to construct the remaining properties which I will pass as input to the constructor. I was then thinking that I should be able to call two more functions in the methods section to fill in the remaining properties... see pseudocode below...
methods
function obj=myConstructor(input)
obj.property1=input;
getProperty2(obj);
getProperty3(obj);
end
function getProperty2(obj)
obj.property2 = do something and save in property2...
end
function getProperty3(obj)
obj.property3 = do something and save in property3...
end
end
However, when I try and run this, neither property 2 or 3 are assigned... only the value that I pass to the constructor. Any help/ideas on how to accomplish the initialization would be much appreciated. Thanks.
First of all, get methods are usually used to retrieve (i.e. get) the value of a property of an object. Not to calculate something.
Next, the MATLAB object model has two different kinds: value objects and handle objects. The distinction is important, but as you don't mention any, I will assume you are using value objects. The behavior for handle objects is totally different.
In contrast to e.g. Java and most other languages, you need to return the changed object. So in MATLAB this would be something like:
classdef MyClass
properties
p1, p2, p3;
end
methods
function obj = MyClass(input)
obj.p1 = input;
obj = obj.calculateP2(input);
obj = obj.calculateP3(input);
end
function obj = calculateP2(obj, input)
obj.p2 = someLengthyCalculation(input);
end
function obj = calculateP3(obj, input)
obj.p3 = someOtherLengthyCalculation(input);
end
end
end
This can be made more clean, as most likely the calculateP? methods belong better as private static methods. This all depends on how much you want to pass to these methods.