I'm grouping a set of anonymous functions into a structure and some variables within that structure. Is there a way to refer 'self', i.e, own structure? What I'd like to accomplish is to have a function returns some values based on the member variables. For simplicity, say I have a struct
a, where
a.value_1 = 3;
a.value_2 = 2;
a.sum = @()(self.value_1 + self.value_2)
Is there something like that possible in MATLAB?
Before objected-oriented programming was introduced in MATLAB (including both classdef
-style and the obsolete @-directory style classes), one could create lightweight objects using closures and nested functions (lacking inheritance of course). This concept also exists in other languages.
Here is an example:
function s = mystruct()
s = struct('value_1',[], 'value_2',2, 'sum',@mysum);
s.value_1 = 3;
function out = mysum()
out = s.value_1 + s.value_2;
end
end
Which is used as:
>> s = mystruct()
s =
value_1: 3
value_2: 2
sum: @mystruct/mysum
>> s.value_1 = 10; % NOTE: this wont do what you expect!
>> s.sum()
ans =
5
Note that variables are immediately captured when creating a closure (functions have their own private copy if you will). So if you change one of the exposed fields from the returned structure, it will not be reflected in the enclosed state (think of them as read-only properties).
One solution is to provide accessor methods:
function obj = mystruct()
% think of those as private properties
value_1 = 3;
value_2 = 2;
% returned object (this or self)
obj = struct();
% public accessors for properties
obj.value_1 = @accessValue1;
function out = accessValue1(in)
if nargin > 0, value_1 = in; end
out = value_1;
end
obj.value_2 = @accessValue2;
function out = accessValue2(in)
if nargin > 0, value_2 = in; end
out = value_2;
end
% member method
obj.sum = @mysum;
function out = mysum()
out = value_1 + value_2;
end
end
So now we could say:
>> s = mystruct()
s =
value_1: @mystruct/accessValue1
value_2: @mystruct/accessValue1
sum: @mystruct/mysum
>> x = s.value_1(); % get
>> s.value_1(10); % set
>> s.sum()
ans =
12
Which is starting to look like the current recommended approach to create classes:
classdef mystruct < handle
properties
value_1 = 3;
value_2 = 2;
end
methods
function out = sum(obj)
out = obj.value_1 + obj.value_2;
end
end
end
Used in a similar manner:
>> s = mystruct()
s =
mystruct with properties:
value_1: 3
value_2: 2
>> s.value_1 = 10;
>> s.sum
ans =
12
We could also define get/set access methods as before..
This seems to work but I think you should rather create a class
than a struct
to do this:
a.value_1 = 3;
a.value_2 = 2;
a.sum = @(x)(x.value_1 + x.value_2)
a.sum(a)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With