Why do some Matlab class methods require "apparently" unnecessary output argument - matlab

After evolving my project code for months, I've finally hit a need to define a new class. Having to romp through my previous class definitions as a refresher of the conventions, I noticed that all constructors and property setters all have an output argument, even though nothing is assigned to it, e.g.:
function o = myConstructor( arg1, arg2, ... )
function o = set.SomeProperty( o, arg1 )
I've been looking through the documentation for upward of an hour without finding the explanation for this. It doesn't look like it depends on whether a function is defined in the class definition file or in its own separate m-file.
Can anyone please explain?

The best place to start is the documentation "Comparison of Handle and Value Classes". From the very top:
A value class constructor returns an object that is associated with the variable to which it is assigned. If you reassign this variable, MATLAB® creates an independent copy of the original object. If you pass this variable to a function to modify it, the function must return the modified object as an output argument.
A handle class constructor returns a handle object that is a reference to the object created. You can assign the handle object to multiple variables or pass it to functions without causing MATLAB to make a copy of the original object. A function that modifies a handle object passed as an input argument does not need to return the object.
In other words, value classes need to return a modified object (which is a new object distinct from the original), while handle classes don't. The constructor of either class will always have to return an object, since it is actually constructing it.
Some good additional reading is "Which Kind of Class to Use", which links to a couple helpful examples of each type of class object. Looking at the DocPolynom value class example, you can see that property set methods have to return the modified object, while the dlnode handle class example only requires an output for its constructor. Note that you could still return an object from a handle class method (if desired), but it's not required.

Related

Syntax of call to super class constructor

Within a subclass constructor, what is the difference between calling obj#SuperClass(a,b); and obj = obj#SuperClass(a,b);
Both are found in doc, for ex. here
The canonical syntax for calling a superclass constructor is
obj = obj#SuperClass(args)
(see the documentation).
This is comparable to calling any constructor, where the output of the function call is assigned to a variable:
obj = SuperClass(args)
However, because the superclass constructor must initialize fields inside a (larger) derived object, the obj to be modified must be passed in some way to the function call, hence the (awkward) obj# syntax.
But because we pass the object to be initialized, which is modified, we don’t really need to capture that output any more. Hence the other form,
obj#SuperClass(args)
does exactly the same things in all situations I have encountered.
There is no difference that I can see. I would be surprised if the first syntax did any data copying whatsoever, that has most certainly been optimized out, just like obj = obj.method(args) doesn’t copy the object.

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.

What does at # mean in MATLAB when creating an instance of a class?

For example:
function s = slexpdatasetSLAP()
s = s#slexpdataset('slapCC','SLAP dataset for collective classification'); %slexpdataset is a class defined in another .m file
s.discription ='CC';
end
As I know, # is used as creating a function handle in MATLAB, but obviously that interpretation is not suitable in this context. So what does that at # mean?
This is the syntax for calling the constructor of the super-class
In general, for calling a method of the superclass, you'd use the syntax
outputs = methodName#superclassname(obj, input, arguments)
However, calling the constructor is a little different since you use the variable name for your object's instance in place of methodName in the example above
obj = obj#superclassname(input, arguments)
In your case, rather than obj, you're using s as the variable to refer to the class instance (since you define that as the output from your constructor), so you're essentially calling the constructor of slexpdataset and passing it the list of arguments shown.

Why doesn't inout pass by reference?

I'm doing something like this:
someFunction(&myClass)
where someFunction sorts an array on myClass.
someFunction(inout someclass:ClassA) {
someClass.sort({$0.price > $1.price})
}
If I print myClass after the function call, I notice the array is still unsorted. From what I know, Swift passes values by copy. But when I use inout, shouldn't it change to pass by reference?
This is because class instances and functions are reference types. Ints, structs, and everything else are value types. When you pass a reference type into a function as a parameter, you are already going to be referencing that instance. When you pass a value type as a parameter, the function gets a copy of that variable (by default), so inout is usually (see edit) only needed if you want to alter a value type from inside of a function.
Altering a class instance without & or inout:
More details
When you create a reference type var t = myClass(), you're really creating a variable t that is a pointer to a myClass instance in memory. By using an ampersand &t in front of a reference type, you are really saying "give me the pointer to the pointer of a myClass instance"
More info on reference vs value types: https://stackoverflow.com/a/27366050/580487
EDIT
As was pointed out in the comments, you can still use inout with reference types if you want to alter a pointer, etc, but I was trying to shed light on the general use case.
Below is an example of sorting an array inside of a function:
If you post your code here, it would be more meaningful. BTW, look at below links that might helpful for you,
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html#//apple_ref/doc/uid/TP40014097-CH10-ID173
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/doc/uid/TP40014097-CH34-ID545

How to set up classes

i am an engineering student enrolled in computer programming trying to understand a practice assignment for an upcoming lab and was wondering if someone could help me with this step of my program, Step: using The init method for the class takes the first formal parameter self and a list of [x, y] pairs v and stores the list as a class instance variable
It sounds like you are using Python, but next time you post a question, make sure you specify that and tag your question as such. You are looking for something like the following code:
class MyClassName(object):
def __init__(self, pairs):
self.pairs = pairs
Let's look at this line by line:
class MyClassName(object):
The first line declares a class called MyClassName. It extends object, which is not super important to understand right now, but is basically saying that MyClassName is a particular type of object.
def __init__(self, pairs):
The second line creates a function called __init__ which will be called when you instantiate an object of type MyClassName. This line also declares what parameters it takes. It sounds like you already know that the first argument has to be self, and the second parameter, pairs, is the list of [x,y] pairs. In python, we don't need to specify what type these parameters are, so we need only to name them (Some languages would require us to specify that pairs is going to be a list of pairs).
self.pairs = pairs
Now all we have to do is set the instance variable. Inside a class, self refers to this particular instance of the object. In other words, every time we create a variable of type MyClassName, the self keyword will refer to that particular instance of the object, rather than to all instances of MyClassName. So in this case, self.pairs refers to the variable pairs in this particular instance of MyClassName. On the other hand, pairs simply refers to the argument passed into the function __init__.
So, to put all this together, we have defined a class called MyClassName, then defined the __init__ function, and in it, we set the instance variable self.pairs to be equal to the pairs variable passed into __init__.
Last, I'll give a quick example of how to instantiate MyClassName:
my_list = [(1,1),(2,4),(3,9),(4,16)]
my_instance = MyClassName(my_list)
Good luck!
[Edit] Also, I agree with the first comment on your question. You need to be more clear and verbose in exactly what you are trying to accomplish and not leave it up to guess work. In this case, I think I could tell what you were trying to do, but it may not always be clear.