On Oct 25, 2005, at 10:26 AM, David Bateman wrote:
Paul Kienzle wrote:
On Oct 24, 2005, at 9:20 AM, David Bateman wrote:
However, nested functions are not permitted with Paul's test
infrastructure. I haven't looked at test.m yet to see, but how
complicated would it be to include nested functions in test.m?
You should now be able to build test function blocks with the
function name being the name of a shared variable which will last
until the end of the test or until the next 'shared' block.
A further problem is the case
%!function x = a()
%! x = 2;
%!assert(a(),2); # Test a test function with no input args
%!assert(a,2);
The first assert works, but as you used function handles to implement
the nested functions, then "a()" works correctly but "a" gives the
string value of the function handle rather than calling the function
handle itself. This is compatiable behaviour. Without using function
handles I see no other way to treat this other than adding the empty
parenthesis in the perl script...
1. It would be useful in another context (octave as engine for a
separate application) to allow 'evalin' to take the name of a context
rather than just 'base' or 'caller'. If a function definition within
an evalin would be entered into the evalin symbol table, this would
given me the private namespace I want for my function without
introducing function handles.
This would also be a cleaner way to support shared variables. Instead
of wrapping code blocks in a function and passing in and returning the
shared variables, I would just evalin('__test__',code). This context
could be kept around when if a test fails so it would be easier to
debug the tests. I'm not sure what would happen with
evalin('__test__','keyboard'),
but the following does the right thing:
octave:1> function a, x=1; b; end
octave:2> function b, x=2; evalin('caller','keyboard'); x, end
octave:3> a
keyboard: stopped in evalin at line 2
debug> x
x = 1
debug> exit
x = 2
2. We could define an 'alias' function which pushes the new definition
of a function on top of the old. Define the private function as
__test_f### as I currently am, then alias it to the correct name. At
the end of the test clear the name and
the original definition reappears.
3. An ugly alternative would be to define an new function handle type
which acted like a function in all contexts. This sounds much too
special purpose.
4. An even uglier alternative is to map all occurrences of private
function name a to __test_a within the code blocks.
All of these are a lot more work than I can do right now, so I guess
you are stuck with perl hacking. :-(
- Paul