[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Forcing Variable Outputs
From: |
John W. Eaton |
Subject: |
Forcing Variable Outputs |
Date: |
Wed, 29 Mar 2006 00:45:32 -0500 |
On 28-Mar-2006, Bill Denney wrote:
| I have a function that I want to force to have a variable number of output
| arguements based on its calling function's number of output arguements.
| In other words, I want to do something like
|
| function [varargout] = fxn1(varargin)
|
| varargout{:} = fxn2(varargin{:});
|
| endfunction
|
| and I want fxn2 to see the same number of output arguements that fxn1
| sees.
|
| I thought of initializing varargout like
|
| varargout = cell(1, nargout);
|
| but that didn't work. Is there a way to do this?
I think what you want is
function varargout = fxn1 (varargin)
varargout = cell (nargout, 1);
[varargout{:}] = fxn2 (varargin{:});
endfunction
but this feature of Matlab is not yet implemented in Octave. The
reason it is not done yet is that decoding the LHS of the assignment
[varargout{:}] = fxn2 (varargin{:});
must be done before the function on the RHS is called so that nargin
may be set properly when the function is called, and doing that in the
general case is relatively complex and may require partial evaluation
of the expression inside the square brackets on the LHS. For example,
think about a case like
[foo(i,j(k),f(x,y,z)).bar{s:t}] = fxn2 (...);
the index expressions used here could be functions with side effects,
etc. To know precisely how many elements are in the comma-separated
list on the LHS, the expression must be evaluated. I'm not sure what
is reasonable in a complex case like this, or what Matlab does. Even
if function calls are not allowed inside an expression like this,
implementing this feature requires a significant change to the way
Octave works because Octave currently evaluates the LHS after the RHS
(all we do is count the number of expressions in the list inside the
square brackets on the LHS, and set nargout to that number).
Note that in Octave it is possible to write
function varargout = f1 (varargin)
varargout = cell (nargout, 1);
[varargout{:}] = f2 (varargin{:});
endfunction
function varargout = f2 (varargin)
nargin
nargout
varargout = varargin;
endfunction
and things appear to work for a call like
octave:8> [a,b,c] = f1 (1,2,3)
ans = 3
ans = 1
a = 1
b = 1
c = 1
except that nargout is wrong in the call to f2. It should be 3
instead of 1.
But maybe it would be relatively simple to correctly handle simple
cases like the one in your example above, and implementing that might
get 90% of the uses of this kind of feature.
BTW, even this feature does not allow you to eliminate all checks on
nargout because it will fail (in Matlab) if you call fxn1 with no
output values to assign, so you still need to handle that case:
function varargout = fxn1 (varargin)
if (nargout > 0)
varargout = cell (nargout, 1);
[varargout{:}] = fxn2 (varargin{:});
else
fxn2 (varargin{:});
endif
endfunction
But this seems like a missing feature/bug in Matlab. Why not simply
set nargout to 0 if varargout is empty in the expression
[varargout{:}]? Am I missing something here?
jwe
-------------------------------------------------------------
Octave is freely available under the terms of the GNU GPL.
Octave's home on the web: http://www.octave.org
How to fund new projects: http://www.octave.org/funding.html
Subscription information: http://www.octave.org/archive.html
-------------------------------------------------------------