MATLAB App Designer reset properties - matlab

I have defined a list of private properties in MATLAB App Designer which are initialized as follows:
properties (Access = private)
prop1 = val1;
prop2 = val2;
...
end
I would now like to have a function that resets them to the default values as defined above. Is there an way to do this automatically or do I have to reset them manually (which can lead to errors e.g. when more properties are added)?
Also, is there a way to loop over all the properties I've defined in this way?

If you want to blanket reset only the private properties, you can use metaclass to access the attributes of your properties and adjust as necessary.
For example:
classdef SOcode < handle
properties
a
b
end
properties (Access = private)
c = -1
d = -1
end
methods
function self = SOcode()
end
function changeprivate(self)
self.c = randi(5);
self.d = randi(5);
end
function printprivate(self)
fprintf('c = %d\nd = %d\n', self.c, self.d)
end
function resetprivate(self)
tmp = metaclass(self);
props = tmp.PropertyList;
nprops = numel(props);
for ii = 1:nprops
if strcmp(props(ii).SetAccess, 'private')
self.(props(ii).Name) = props(ii).DefaultValue;
end
end
end
end
end
Provides the desired behavior:
>> test = SOcode;
>> test.changeprivate;
>> test.printprivate;
c = 1
d = 1
>> test.resetprivate;
>> test.printprivate;
c = -1
d = -1

Related

How to find and check obects with all properties being empty in Matlab?

For example, I create a student with all properties being empty
classdef student < handle
properties
name
test
end
methods
function obj = student(name)
if nargin==1
obj.name = name;
obj.test = test();
end
end
end
end
>> A=student
A =
student with properties:
name: []
test: []
>> isempty(A)
ans =
logical
0
But the output of isempty(A) is false. So what function can check if all properties of an object are empty? And How to find that kind of objects in a database?
You can overload the isempty method for your class:
classdef student < handle
properties
name
test
end
methods
function obj = student(name)
if nargin==1
obj.name = name;
obj.test = test();
end
end
function res = isempty(obj)
res = isempty(obj.name) && isempty(obj.test);
end
end
end
Now:
>> A = student;
>> isempty(A)
ans =
logical
1
To find empty objects in a database, iterate over the elements in the database and check if they're empty.
Not many more choices than to loop through the properties of your object to check if they are all empty or not:
function isE = check_emptyness(A)
props = properties(A);
isE = true;
for iprop = 1:length(props)
if ~isempty(A.(props{iprop}))
isE = false;
break
end
end
end
student_arr=[student('A') student()];
check_emptyness(student_arr(1))
ans =
logical
0
check_emptyness(student_arr(2))
ans =
logical
1

In matlab, I got different values in a method of class and out

In the matlab, I defined a class and instantiated the class in another script, but I got different values in and out of the method. My matlab code are shown bellow:
test_add.m
classdef test_add
properties
a
b
end
methods
function obj = test_add(a, b)
obj.a = a;
obj.b = b;
end
function c = add_1(obj)
c = obj.a + 1;
end
function inter(obj, t)
for i = 1:t
obj.a = obj.add_1();
end
fprintf('In the method:\n');
fprintf('a = %d\n',obj.a);
fprintf('b = %d\n',obj.b);
disp('=======================');
end
end
end
main.m
tt = test_add(1,2);
tt.inter(3);
fprintf('Out of the method:\n');
fprintf('a = %d\n',tt.a);
fprintf('b = %d\n',tt.b);
output:
In the method:
a = 4
b = 2
=======================
Out of the method:
a = 1
b = 2
In Matlab there are two type of classes: handle class and Value class. If you said nothing you get the Value class. Most of the OO languages out there are using handle class semantic.
So, you have two options:
Change you class to handle class by inheriting from handle
classdef test_add < handle
Stay with Value class and change your inter function to return obj.
But then, in main call obj=tt.inter(3) to get the updated object.
function obj = inter(obj, t)
for i = 1:t
obj.a = obj.add_1();
end
fprintf('In the method:\n');
fprintf('a = %d\n',obj.a);
fprintf('b = %d\n',obj.b);
disp('=======================');
end
It's a problem of value class vs handle class, the solution is:
test_add.m
classdef test_add < handle
...
end
Then, the output is:
In the method:
a = 4
b = 2
=======================
Out of the method:
a = 4
b = 2

matlab how to call a class method that changes prop from another class method

If I call a method (receiving and returning obj) it changes my property.
But if I call that method from another method it fails. I tried all kinds of ways but still failing.
classdef AClass
properties
A;
end
methods
function obj = ChangeA(obj, v)
obj.A = v;
end
function obj = CallChangeA(obj)
obj.ChangeA(4);
%obj = obj.ChangeA(4);
%ChangeA(obj, 4);
%obj = ChangeA(obj, 4);
% none of these works
end
end
end
% ------ script:
a1 = AClass;
a1.A = 1;
a1.ChangeA(2); % a1.A = 2
a2 = AClass;
a2.A = 3;
a2.CallChangeA(); % a2.A = 3 !!! not four
How do I write the code so calling from 1 method to the other updates the property?
Other than the obvious typos in your example code, as I commented above, I would highly suggest taking a look at the difference between MATLAB's Handle and Value classes. By default, MATLAB classes are value classes, so each time the object is passed to a function an independent copy is created. If you're making changes to this object then you need to return it as an output:
classdef AClass
properties
A;
end
methods
function obj = ChangeA(obj, a)
obj.A = a;
end
function obj = CallChangeA(obj)
obj = obj.ChangeA(4);
end
end
end
Which functions as expected:
>> a1 = AClass;
>> a1.A = 1
a1 =
AClass with properties:
A: 1
>> a1 = a1.CallChangeA()
a1 =
AClass with properties:
A: 4
Handle classes, on the other hand, are references to a single underlying object, allowing for (among other things) in place modification of the object:
classdef AClass < handle
properties
A;
end
methods
function ChangeA(obj, a)
obj.A = a;
end
function CallChangeA(obj)
obj.ChangeA(4);
end
end
end
Which also functions as expected:
>> a1 = AClass;
>> a1.A = 1;
>> a1.A
ans =
1
>> a1.CallChangeA()
>> a1.A
ans =
4

Use one set method for multiple properties MATLAB

I have several properties that use essentially the same set method:
classdef MyClass
properties
A
B
end
methods
function mc = MyClass(a,b) % Constructor
mc.A = a;
mc.B = b;
end
function mc = set.A(mc, a) % setter for A
if a > 5
mc.A = a;
else
error('A should be larger than 5');
end
end
function mc = set.B(mc, b) %setter for B
if b > 5
mc.B = b;
else
error('B should be larger than 5');
end
end
end
end
Is there a way to use only one set function for variables A and B? (Please note that the error function use the property names as strings.)
Is it suggested to use only one set function? What are the possible drawbacks of using one set function?
The only real way is to extract the common code to another function, and call it from the setters:
classdef MyClass
properties
A
B
end%public properties
methods
function mc = MyClass(a,b) % Constructor
mc.A = a;
mc.B = b;
end
function mc = set.A(mc, value) % setter for A
mc = mc.commonSetter(value, 'A');
end
function mc = set.B(mc, value) %setter for B
mc = mc.commonSetter(value, 'B');
end
end%public methods
methods(protected = true)
function mc = commonSetter(mc, property, value)
if value <= 5;
error([property ' should be less than 5');
end
mc.(property) = value;
end%commonSetter()
end%protected methods
end%classdef

Get properties from another class (matlab)

Is it possbile to get properties from another class in MatLab?
I have two classes: ProjectTableand AllProjectTables.
In ProjectTable I have tried with the following:
properties (GetAccess = ?AllProjectTables)
But it doesn't work.
Here is a working example:
classdef ProjectTable
properties (GetAccess = ?AllProjectTables)
Value
end
methods
function obj = ProjectTable(val)
obj.Value = val;
end
function r = addTwo(obj)
r = obj.Value + 2;
end
end
end
classdef AllProjectTables
properties
Project_Table
end
methods
function obj = AllProjectTables(project_table)
obj.Project_Table = project_table;
end
function r = test(obj)
r = obj.Project_Table.Value;
end
end
end
And test:
>> a=ProjectTable(45)
a =
ProjectTable with no properties.
>> a.Value
You cannot get the 'Value' property of ProjectTable.
>> b=AllProjectTables(a)
b =
AllProjectTables with properties:
Project_Table: [1x1 ProjectTable]
>> b.test
ans =
45
>> b.Project_Table.Value
You cannot get the 'Value' property of ProjectTable.
>>