In R2018b, I have the following setup:
classdef SomeClass < handle
methods
function SomeMethod(obj)
disp in!
end
end
end
classdef SomeOtherClass < handle
properties (Constant)
instance = SomeClass()
end
methods
function Test(obj)
hdl = @obj.instance.SomeMethod;
hdl();
end
end
end
However, running the Test()
method gives an error:
>> SomeOtherClass().Test()
Undefined function or variable 'obj.instance.SomeMethod'.
Changing the Test()
method to:
function Test(obj)
A = obj.instance;
hdl = @A.SomeMethod;
hdl();
end
gives the desired result:
>> SomeOtherClass().Test
in!
I'm puzzled...why do I need the middle man A
?
Following @gnovice's finding:
>> obj = struct('instance', SomeClass());
>> hdl = @obj.instance.SomeMethod
hdl =
function_handle with value:
@obj.instance.SomeMethod
>> hdl(obj.instance)
Undefined function or variable 'obj.instance.SomeMethod'.
>> hdl()
Undefined function or variable 'obj.instance.SomeMethod'.
But:
>> instance=SomeClass();
>> hdl = @instance.SomeMethod
hdl =
function_handle with value:
@(varargin)instance.SomeMethod(varargin{:})
>> hdl(instance)
Error using SomeClass/SomeMethod
Too many input arguments.
Error in @(varargin)instance.SomeMethod(varargin{:})
>> hdl()
in!
Note how the function handle created in this second case is actually an anonymous function, which includes the object in it. This is a special case of the @
operator, not the normal usage, which would be:
>> hdl=@SomeMethod
hdl =
function_handle with value:
@SomeMethod
>> hdl(instance)
in!
What this case actually does is create an anonymous function that embeds the object you intend to call this method on. You can create such a function this way:
>> hdl=@()obj.instance.SomeMethod()
hdl =
function_handle with value:
@()obj.instance.SomeMethod()
>> hdl()
in!