Error with function handles of object methods

Jaroslav Hajek highegg at gmail.com
Fri Jul 24 00:12:21 CDT 2009


On Thu, Jul 23, 2009 at 10:45 PM, John W. Eaton<jwe at octave.org> wrote:
> On 24-Jun-2009, WMennerich wrote:
>
> | Hello,
> | I found a bug using objects:
> | In short words: Function handles of object functions (methods) within
> | the class directory (beginning with '@') can not be created.
> |
> | I use Octave V3.2.0 (mingw binary) on WindowsXP.
> |
> | I hope, this bug report contains enough details,
> | otherwise just ask please.
> |
> |
> | W.Mennerich
> |
> |
> |
> | In the following the tests I made:
> |
> |
> |
> |
> |
> | function test (<scalar>,<scalar>)
> | [constructor in the '@test' directory
> | *********************************
> | function newtest=test(att1, att2)
> | %constructor
> |
> | switch nargin
> | case 0
> | newtest.att1=[];
> | newtest.att2=[];
> | case 2
> | newtest.att1=att1;
> | newtest.att2=att1+att2;
> | end
> |
> | newtest=class(newtest,'test');
> | **********************************
> |
> |
> | function sumAtts(<test>)
> | [a method in the '@test' directory
> | **********************************
> | function res=sumAtts(this)
> | res=this.att1+this.att2;
> |
> |
> |
> | function get(<test>,<string>)
> | [for testing function overloading,
> | also inside '@test']
> | **********************************
> | function att=get(this,nameAtt)
> | att=this.(nameAtt);
> |
> |
> |
> | Test environment:
> | ##################################
> | ##################################
> |
> | * Create all files
> |
> | * Create '@test'
> |
> | * Put all files into '@test'
> |
> | * Put '@test' into octave path
> |
> |
> |
> | Running the tests:
> | ##################################
> | ##################################
> |
> | %Testing the class:
> | %create three objects and put them into a cell array:
> |
> | mytest1=test(33,44)
> | mytest2=test(66,88)
> | mytest3=test(132,176)
> |
> | allmytests={mytest1 mytest2 mytest3}
> |
> |
> | %Workspace of octave shows:
> |
> |
> |   Attr Name            Size                     Bytes  Class
> |   ==== ====            ====                     =====  =====
> |        allmytests      1x3                         48  cell
> |        mytest1         1x1                         16  test
> |        mytest2         1x1                         16  test
> |        mytest3         1x1                         16  test
> |
> |
> |
> |
> |
> | %Testing of the sumAtts(<test>) function:
> |
> | > sumAtts(mytest1)
> | ans =  110
> |
> |
> | > sumAtts(mytest2)
> | ans =  220
> |
> |
> | > sumAtts(mytest3)
> | ans =  440
> |
> |
> |
> |
> |
> |
> | %Function 'sumAtts' as input of an anonymous function works:
> |
> | > cellfun(@(x) sumAtts(x),allmytests)
> | ans =
> |
> |    110   220   440
> |
> |
> |
> | %Also the (overloaded) function  'get' works fine:
> | > cellfun(@(x) get(x,'att1'),allmytests)
> | ans =
> |
> |     33    66   132
> |
> |
> | %Using cellfun with a sumAtts handle does not work:
> |
> | > cellfun(@sumAtts,allmytests)
> | error: error creating function handle "@sumAtts"
> | error: evaluating argument list element number 1
> | error: error creating function handle "@sumAtts"
> | error: evaluating argument list element number 1
> |
> |
> | %The same also with overloaded 'get' function, gives another error:
> |
> | > inStrings={'att1' 'att1' 'att1'}
> | inStrings =
> |
> | {
> |   [1,1] = att1
> |   [1,2] = att1
> |   [1,3] = att1
> | }
> |
> | > cellfun(@get,allmytests,inStrings)
> | error: octave_base_value::array_value(): wrong type argument `class'
> | error: get: expecting graphics handle as first argument
>
> Jaroslav's recent changes seem to fix this problem, but
>
>  cellfun(@sumAtts,allmytests)
>
> still doesn't work for me.
>
> | %Try to create a function handle outside of cellfun:
> |
> | > fun=@sumAtts
> | error: error creating function handle "@sumAtts"
>
> Jaroslav, is this supposed to work now?
>
> jwe
>

Currently, a non-overloaded version of the function must exist, so
that there's always at least one function to dispatch to. Quoting
Matlab docs:
"At the time you create a function handle, the function you specify
must be on the MATLAB path and in the current scope."

This seems to me to suggest that Matlab requires the same. If not,
then I would prefer if someone investigated what exactly the Matlab
requirements are.

We can easily relax the behavior - not require the base function to
exist and let the handle gripe when referenced and no dispatch is
found. The downside is that mistyped references like @nonexistingname
will not give an error at the time of construction.
To overcome this, one would need to search all overloads, and that
requires something like load_path::any_method, able to query whether a
method with a given name exists in any class, which AFAIK isn't
currently there.

Now that I think of it, this sounds like an useful extension even if
Matlab doesn't actually allow it, so I'll try to do something.

regards

-- 
RNDr. Jaroslav Hajek
computing expert & GNU Octave developer
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz



More information about the Bug-octave mailing list