Is it possible to attach a function to a class property of type struct? Intended usage:
% Definition:
classdef a < handle
properties
bar
end
methods
function obj = a()
obj.bar = struct;
%obj.bar.attachFunction('apply', #someFunction); <-- something like this
end
end
end
% Usage:
foo = a();
foo.bar.apply('test');
foo.bar.var1 = 1;
foo.bar.var2 = 2;
Oh well, that was actually quite simply once I used my mind.
classdef a < handle
properties
bar
end
methods
function obj = a()
obj.bar = struct;
obj.bar.apply = #(str) #obj.barApply(str);
end
end
methods (Access=protected)
function barApply(obj, str)
obj.bar.something = str;
end
end
end
foo = a();
foo.bar.apply('monkey');
foo.bar.apple = 2;
Related
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
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
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
I have 2 similar classes:
classdef class1 < handle
properties (Access = public)
b
end
properties (Access = private)
a
end
methods (Access = public)
function this = class1()
this.a = 1;
this.b = 1;
end
function test(this)
'Inside class'
this.a
this.b
this.a = 2;
this.b = 2;
end
end
end
And the second:
classdef class2
properties (Access = public)
b
end
properties (Access = private)
a
end
methods (Access = public)
function this = class2()
this.a = 1;
this.b = 1;
end
function test(this)
'Inside class'
this.a
this.b
this.a = 2;
this.b = 2;
end
end
end
One time I inherit from handle. Other one I don't do it. After I create such script:
solver1 = class1();
solver1.b
solver1
solver1.test()
solver1.b
solver1
solver1.test()
solver2 = class2();
solver2.b
solver2
solver2.test()
solver2.b
solver2
solver2.test()
If I debug my program step by step, I see that a and b haven't changed in the second class after solver2.test(). But the first class these variable have changed after solver1.test(). What resasons this issue?
I solve this problem with next way. I declare global variable into class. And after this, I can check this any variable in and out class. This is bad way, but it's work.
I'd like to change my class properties with a method defined for that class:
classdef triangle<handle
properties
a
h
end
methods
function obj = triangle()
obj;
end
function obj = setProps(obj, a, h)
obj.a = a;
obj.a = h;
end
end
end
Calling:
t = triangle();
t.setProps(a, h);
It's not working at all - I get this error:
The class 'handle' is not a super-class of class 'triangle', as required to invoke a super-class constructor or method.
Error in triangle (line 13)
function obj = triangle()
I'm using matlab 2012a. My code is based on this example: link
Try clear before doing this. It is possible that you've overwritten handle with something. Otherwise, this works for me on Matlab 2012a:
clear;
a = 'hello';
h = 1;
t = triangle();
t.setProps(a, h);