Как обернуть функцию, используя varargin и varargout? - PullRequest
31 голосов
/ 04 февраля 2011

мини-пример:

function varargout = wrapper(varargin)
varargout = someFunction(varargin);

Вот как бы я это сделал первым.Но, например, если someFunction = ndgrid, то это приводит к ошибке, не определенной для массивов ячеек, поэтому при следующей попытке вместо этого использовался someFunction(varargin{:}).Это успешный вызов, но вызов [a,b] = wrapper([1,2], [3,4]) не дает тот же результат, что и прямой вызов ndgrid, так что я делаю не так?

Ответы [ 3 ]

36 голосов
/ 06 февраля 2011

На самом деле, ответ Михаила не совсем правильный.В случае, когда someFunction является функцией, которая возвращает значение, даже если ни один не запрашивается, то есть, как функция указывает, что значение должно быть присвоено ans, оболочка Михаила потерпит неудачу.Например, если someFunction были заменены на sin, и вы сравнили запущенную оболочку с запущенным sin напрямую, вы увидите:

>> wrapper(0)
>> sin(0)

ans =

   0

Правильный способ сделать это -

function varargout = wrapper( varargin )
[varargout{1:nargout}] = someFunction( varargin{:} ); 

.Причина, по которой это работает, связана с малоизвестным крайним случаем в правилах индексации MATLAB, который существовал именно для этого случая, по крайней мере, с R2006a (возможно, дольше).Это что-то вроде бородавки в индексации MATLAB, но было сочтено необходимым справиться с подобными вещами.

Правило:

При выполнении присвоения с подпиской, если

  • присваивание-присвоение неинициализированной переменной, И
  • неинициализированная переменная индексируется фигурными скобками, И
  • индекс в фигурных скобках пуст, И
  • слева-боксовая сторона появляется внутри квадратных скобок, и
  • правая часть разрешает значение / возвращает вывод

Тогда неинициализированной переменной присваивается скалярная ячейка, содержащая возвращаемое значениепо правой стороне.

Например:

>> clear uninit % just to make sure uninit is uninitialized
>> [uninit{[]}] = sin(0)

uninit = 

    [0]
7 голосов
/ 04 февраля 2011
function varargout = wrapper( varargin )

if ~nargout
    someFunction( varargin{:} ); 
else
    [varargout{1:nargout}] = someFunction( varargin{:} ); 
end
1 голос
/ 04 февраля 2011

Если количество выходных аргументов совпадает с количеством входных аргументов, вы можете использовать

function varargout = wrapper(varargin)
[varargout{1:nargin}] = someFunction(varargin{:});

Это прекрасно работает с ndgrid.

...