evolved
evolved

Reputation: 2210

Matlab anonymous callback function arguments

Following this example of a Model View Controller GUI in Matlab, I have a question regarding the anonymous function callback input arguments

Here is the a view function that creates the gui handles and passes them as an input argument to the onChanged callback function.

function handles = View_TimeDomain(m)
    %VIEW  a GUI representation of the signal model

    % build the GUI
    handles = initGUI();
    onChangedF(handles, m);    % populate with initial values

    % observe on model changes and update view accordingly
    % (tie listener to model object lifecycle)
    addlistener(m, 'f', 'PostSet', ...
        @(o,e) onChangedF(handles,e.AffectedObject));
end

The first thing that I don't quite understand is that according to the Matlab documentation the first argument must be the source of the event and the second arument must be the event data (Matlab doc1, Matlab doc2) but in this case it is handles. When the event is triggered, the following onChangedF function is called as expected.

function onChangedF(handles, model)
    % respond to model changes by updating view
    if ~ishghandle(handles.fig), return, end
    set(handles.line, 'XData',model.t, 'YData',model.data)
    set(handles.slider, 'Value',model.f);
end

However, in this case handles is the struct containing the handles defined using initGui() and not the event source.

I guess this stems from the definition of the anonymous function:

@(o,e) onChangedF(handles, e.AffectedObject)

Am I correct, assuming that o is the source which is not used in the onChangedF function input. Can someone explain why this syntax of an anonymous function is valid? I thought that o needs to be an argument of this specific callback function as well. Something like this:

@(o,e) onChangedF(o, handles, e.AffectedObject)

where additional arguments are appended (at the end) of the function. And then just avoid this unused argument using ~:

function onChangedF(~, handles, model)
    % respond to model changes by updating view
    if ~ishghandle(handles.fig), return, end
    set(handles.line, 'XData',model.t, 'YData',model.data)
    set(handles.slider, 'Value',model.f);
end

Upvotes: 0

Views: 618

Answers (1)

sco1
sco1

Reputation: 12214

Anonymous functions are a subset of function handles that allow you to fully define functions inline, as opposed to function handles that execute a function that exists elsewhere.

The syntax of an anonymous function is af = @(arglist)anonymous_function, which is functionally the same as:

function af(arglist)
    anonymous_function
end

This means your PostSet callback is functionally equivalent to:

function PostSet(o,e) 
    onChangedF(handles, e.AffectedObject)
end

Which satisfies MATLAB's callback definition requirements.

Because handles is in the function scope when you are creating your PostSet anonymous function, it is available in the scope of the anonymous function callback as well. This is explained in the 'Variables in the Expression' section of the anonymous function documentation. This can also be visualized using the functions function, which provides information about a function handle:

z = 50;
fh = @(x, y) thing(y, z);

fhinfo = functions(fh);
fhworkspace = fhinfo.workspace{1}

Which returns:

fhworkspace = 

  struct with fields:

    z: 50

Upvotes: 1

Related Questions