You can call methods of an object using function handles. Example:
classdef foo
methods
function value=foofun(this)
value=1;
end
end
end
and then
fun=@foofun;
fun(foo);
The handle is just a string I guess, and it doesn't bother Matlab that it can't tell which function is intended before the handle is used. The same handle could even be used to call different methods if different type objects are used as the first parameter.
To capture the outputs of the function you can do this:
outputs=cell(numberOfOutputs,1);
[outputs{:}]=fun(foo);
However, if the function handle was a parameter in the code, then the number of outputs is a problem. For handles to normal functions nargout would solve that, but now nargout can't help because the handle doesn't determine on it's own which function will be called. nargout would need a second input, the type of the object that is going to be used.
It's a bit inelegant to need both the handle and the number of outputs as parameters. Is there another way to call methods indirectly and still capture all the outputs?
Use-case
Imagine a graph with nodes and edges between nodes. Each edge has a few data objects associated with that particular edge. I'm interested in doing various calculations on those data objects.
Examples
- Take all the data objects associated with a specific edge and calculate spectra of those objects.
- Use the prettiest data object from each edge and get the spectra from those objects.
- Choose ten edges randomly, choose randomly one data object from each of those and then compare the objects with a specific, separate, object.
Design
The idea is to separate the selection of the objects and the calculations into different functions. This way the user can combine any calculation with any selection method. Each time a new method is added to the data objects, it can already be called with the existing object selection methods and each time a new selection method is added, it can be used with all the available calculation methods.
A simplified version of a function I'm currently using looks like this
function [ outs ] = callForEach(objects, fun, numberOfOutputs, extraArguments)
for ii=1:length(objects)
out=cell(1,numberOfOutputs);
[out{:}]=fun(objects{ii},extraArguments{ii,:});
outs(ii,:)=out;
end
end
I'd like to be able avoid the parameter numberOfOutputs. It's an inconvenience for the user and it's more error prone to do it like this.
I guess I could just force a same interface for every method: everybody returns a cell array if they need several outputs. I can then assign that cell array, or whatever it is that is returned, into a single cell. However all the built-in functions seem to prefer to use multiple outputs instead, so there's at least a stylistic difference. If I ever wanted to use one of the built-ins as the handle, I'd need to write a wrapper to make the built-in conform to the interface.