Is it possible to view the handle class properties when debugging a matlab function block in simulink?
Currently I have a matlab function block which instantiates a class. In neither the function block or the class itself can I see the properties of the class during debug. My workspace is empty.
When I run who while debugging I only get variables inside the function scope and no persistent variables (in the function block) and no class properties (inside the class itself).
The only way to debug now is to store properties inside a local variable.
Viewing class information is not supported by MATLAB Function block when debugging. The only way is to assign property values to local variables. Documentation at http://www.mathworks.com/help/simulink/ug/how-working-with-matlab-classes-is-different-for-code-generation.html has a line "If you use classes in code in the MATLAB Function block, you cannot use the debugger to view class information.".
classdef foo < handle
methods
function o = my_fcn(obj, in)
my_prop = obj.my_prop;
o = in * my_prop;
end
end
end
In the above code for function my_fcn you can see in, o and my_prop. But not obj.
Related
I have set up a tiny test class with one member variable. I am trying to change this variable within a member function of the class.
I have named the class: "Test"
I've created a new folder: #Test where all methods are inside. The folder looks like this:
In Test.m (the constructor) there is the following code:
function obj = Test()
#member variable
mem.memory = [1,5,2,4,3];
obj = class (mem, "Test");
endfunction
Then I also have the "display" method:
function display(obj)
obj.memory
endfunction
And the method to change the member variable:
function change(obj)
obj.memory = [9,8,7,8,9];
endfunction
the last thing I have is the main script, here I'm creating a new object of the class Test, display it, change it, display it again. This file lies one folder above the #Test folder:
clc
clear all
c = Test();
display(c);
change(c);
display(c);
Here is the output of the program:
Like you can see, the values didn't change to 9 8 7 8 9. It feels like the variable is set to const, but also there comes no error, like: you can not change const variables...
I looked online for some examples, but only could find stange things...
It would be nice, if someone can link me a good tutorial about classes.
You need to change this to
function obj = change(obj)
obj.memory = [9,8,7,8,9];
and then call the method as
c = change(c);
In the MATLAB language, all function inputs are taken by value, not by reference (with the exception of handle classes). Thus, changing the copy of obj inside the function does not change the object in the caller workspace. The copy needs to be returned and assigned to the original variable.
MATLAB does optimize the syntax to not actually make any copies. I think Octave does the same, but am not sure.
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.
Private functions in Matlab are functions stored in a folder with the name "private" and they are only available to the functions immediately above this folder.
I tried the same for classes but Matlab 2016b refused with
A class definition may not be in or below a private directory.
I'm writing a toolbox and I want some internal classes not to be visible within Matlab itself, e.g. they should not appear in the search path, similar to how private behaves for classes in Java or how private functions in Matlab behave.
Is there a way and if so, how can it be done?
There is no way to make a class private in MATLAB. What you can do though, is to place it in a sub-package and it will therefore be placed in a separate namespace from the rest of your package.
+mypackage
+internal
myclass.m
If you want to remove the requirement that you type internal for all your internal functions that need access to your class, you could add a wrapper function in your private folder
+mypackage/private/myclass.m
function obj = myclass(varargin)
obj = mypackage.internal.myclass(varargin{:});
end
If you really want to restrict use of the class by anything outside of your package you could put some logic within the constructor to ensure that the calling class is a member of your package
classdef myclass < handle
methods
function self = myclass()
% Get the path to the package folder
directory = fileparts(fileparts(mfilename('fullpath')));
% Ensure that the function/class that called this was part of te toolbox
S = dbstack('-completenames');
assert(numel(S) > 1 && strfind(S(2).file, directory), ...
'Class only able to be called from the toolbox')
end
end
end
Update
As mentioned by #SamRoberts in the comments, you can also put your constructor within a method block with it's Access restricted to members of the class. You would need to specify each of the classes that you would like to be granted access
classdef myclass
methods (Access = {?mypackage.Class1, ?mypackage.Class2})
function self = myclass()
% Constructor
end
end
end
I defined a class in one of my many MATLAB packages. To my suprise, I could not access a constant property of my class without importing the class definition. Even if it is a method of the class itself. Like so:
classdef TestClass
properties( Constant )
c=0;
end
methods
function obj = TestClass()
end
function getC(obj)
import test.TestClass;
disp(TestClass.c);
end
end
end
I just want to check whether I am doing something wrong here or is this the correct way to use constants in MATLAB.
Since you have placed TestClass inside a package Matlab needs to know where to look to find the definition for this class, even if it's a reference from within the class or function. An alternate to the above code could be:
function getC(obj)
disp(test.TestClass.c);
end
Alternately, if within a class, constant values can be accessed from the object itself.
function getC(obj)
disp(obj.c);
end
If neither of these is working for you, you may need to refresh the classdef for TestClass from memory. This will cause matlab to reload the constant value, which is pulled into Matlab when it first parses the classdef file to determine the structure of the class. This can be done using clear classes, however a warning that it will also clear all other classes, variables, and any breakpoints you have set.
If you want to see if this is necessary you can view the metaclass object to determine what Matlab "thinks" your class structure should be. You can do this using the following.
mc = ?test.TestClass;
mc.PropertyList
You may need to index into the property list to find the specific property you are interested in, but the thing you are looking for are the following fields.
Name: 'c'
Constant: 1
DefaultValue: 0
I'm new to MATLAB OOP. I have an abstract class defining an abstract method in my matlab path. I have a subclass named SubAbsClass in a subfolder named #SubAbsClass. I cannot create an object of the subclass after implementing the abstract method in the subclass. Here's my SubAbsClass implementation:
classdef SubAbsClass < AbsClass
properties
O1
end
methods
function obj=SubAbsClass(a,b)
obj.O1=absMethod(a,b);
end
end
methods (Static)
function out = absMethod(a,b)
out = a + b;
end
end
end
and my abstract class implementation is:
classdef AbsClass
methods(Abstract, Static)
result = absMethod
end
end
when I try to create an object in the MATLAB path (the abstract class is in the MATLAB path), I get an error. I have tried many configurations and searched the matlab oop document, and also the web including stackoverflow but unfortunately couldn't find an example to implement. I appreciate your help
>> clear all; clear classes;
>> obj=SubAbsClass(5,2)
Undefined function 'absMethod' for input arguments of type 'double'.
Error in SubAbsClass (line 11)
obj.O1=absMethod(a,b);
Within a method, Matlab considers non-dot references to be calls to local functions (defined outside the classdef block within the class file) or to a function somewhere on the Matlab path following the usual look-up rules.
So you need to call the Static method via the instance obj in the constructor:
methods
function obj = SubAbsClass(a,b)
obj.O1 = obj.absMethod(a,b);
end
end
One little caveat to the above is that non-Static methods also have a functional form.
So if the method was not Static, this notation would also work
methods
function obj = SubAbsClass(a,b)
obj.O1 = absMethod(obj,a,b);
end
end
Which, I think, is almost equivalent to the dot notation, although it has been said to be "generally" faster (albeit, that was four years ago).
Here are the details for ordinary method invocation and Static method invocation.