установить «помощь» для анонимных функций Matlab - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть длинная анонимная функция, и мне было интересно, можно ли (легко) изменить вывод справки:

>> myfunc=@(x) x; %example anonymous function
>> help myfunc
myfunc is a variable of type function_handle.

Я знаю, что длинные анонимные функции могут быть довольно необычной вещью, тем не менее: может ли это бытьдостигнуто, может быть, с недокументированными функциями, только пока существует дескриптор функции?

Редактировать : комментатор запросил вариант использования: я прочитал об анонимных функциях с несколькими выходами (здесь Лорем об искусстве matlab ), таком как

fmeanVar = @(x) deal(mean(x), var(x));
%a long example function to split a cell array containing 3D matrices into two cell arrays 
myfunc=@(x,c) deal(cellfun(@(d) d(:,:,1:c:end),x),cellfun(@(d) d(:,:,setxor(1:c:end,1:end)),x));

И я хочу убедиться, что я помню, каков второй выходной аргумент, позже, вы знаете ... потому что людизабудь вещи

Ответы [ 3 ]

0 голосов
/ 10 декабря 2018

Проблема в том, что когда вы вызываете help, он перечитывает файл.Когда вы создаете анонимную функцию с

f = @(x) x %Sample text

, она игнорирует %Sample text и таким образом исчезает.Одним из решений является превращение его в структуру, где одно поле является функцией, а другое - справкой.Например, что-то вроде

fMeanVar.fct = @(x) [mean(x), var(x)];
fMeanVar.help = "Second output is the variance"

, например, когда вы хотите использовать функцию, которую вы вызываете

fMeanVar.fct([1,2,3,4])

, и если вы забыли об использовании, вы можете просто позвонить

fMeanVar.help
0 голосов
/ 10 декабря 2018

Вы можете создать свой собственный класс обработки анонимных функций, который будет имитировать эту функцию, скрывая функцию help только для этого типа объекта.

Я написал класс ниже, но сначала покажу, как его использовать, просто нужно иметь класс на своем пути и немного адаптировать способ объявления анонимных функций:

Мы можем переопределить subsref функция также для этого типа класса, то вы можете вызывать дескриптор функции напрямую, используя синтаксис (), а не индексировать в структуру, как предложено ответом Ники .

Обратите внимание, что выдолжен передавать дескриптор, а не имя функции (т.е. help(f) или f.help, а не help f или help('f')).Чтобы обойти это ограничение, вам нужно полностью затенить функцию help, которую я бы не одобрил!

Использование

>> f = anon( @() disp( 'Hi!' ), 'This function displays "Hi!"' );
>> help( f )
Input is a value of type function_handle.
This function displays "Hi!"
>> f()
Hi!

>> f = anon( @(x) x + 10, 'Adds 10 to the input' );
>> help( f )
Input is a value of type function_handle.
Adds 10 to the input
>> f(15:17)
ans = 
  [ 25, 26, 27 ]

>> f.func = @(x) x + 15;
>> f.helpStr = 'Adds 15 to the input'
>> f(15:17)
ans = 
  [ 30 31 32 ]

Функция по умолчаниюдескриптор help сохраняется, если не указан

>> f = anon( @(x) x + 10 );
>> help( f )
Input is a value of type function_handle.

Код класса

Класс может использовать некоторые дополнительные проверки ввода и т. д., но в принципе работает!

classdef anon < handle
    properties ( Access = public )
        helpStr % String to display on help( obj )
        func    % Function handle (meant for anonymouse functions
    end
    methods
        function obj = anon( func, helpStr )
            assert( isa( func, 'function_handle' ) ); % Input check            
            obj.func = func;
            if nargin > 1
                obj.helpStr = helpStr; % Set help string
            end
        end
        function help( obj )
            h = help( obj.func ); % Normal behaviour.
            if ~isempty( obj.helpStr )
                % Custom string (does nothing if empty)
                fprintf( '%s%s\n', h, obj.helpStr );   
            else
                disp( h );
            end
        end
        function varargout = subsref( obj, s )
            % Need to override the subsref behaviour to enable default
            % function calling behaviour!
            switch s(1).type
                case '()'
                    [varargout{1:nargout}]  = obj.func( s(1).subs{:} );
                otherwise
                    [varargout{1:nargout}]  = builtin('subsref', obj, s);
            end
        end
    end
end
0 голосов
/ 10 декабря 2018

В соответствии с документацией Matlab для help это невозможно:

имя справки отображает текст справки для функциональности, указанной именем, такой как функция, метод, класс, набор инструментов или переменная.

Не для дескриптора и не для символов.

...