Error with function handles of object methods

Jaroslav Hajek highegg at gmail.com
Fri Jul 24 01:17:12 CDT 2009


On Fri, Jul 24, 2009 at 7:12 AM, Jaroslav Hajek<highegg at gmail.com> wrote:
> 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
>

Update: using the following patch:
http://hg.savannah.gnu.org/hgweb/octave/rev/0c7d84a65386

I'm now getting:

octave:1> mytest1=test(33,44)
octave:2> mytest2=test(66,88)
octave:3> mytest3=test(132,176)
octave:4>
octave:4> allmytests={mytest1 mytest2 mytest3}
allmytests =

{
}

octave:5> cellfun(@sumAtts,allmytests)
ans =

   110   220   440

octave:6> inStrings={'att1' 'att1' 'att1'}
inStrings =

{
  [1,1] = att1
  [1,2] = att1
  [1,3] = att1
}

octave:7> cellfun(@get,allmytests,inStrings)
ans =

    33    66   132


Further,

octave:8> cellfun(@sumAtts,[allmytests,{1}])
error: no sumAtts method to handle class double
error: cellfun: too many output arguments
octave:8> @xxx
error: error creating function handle "@xxx"

So, everything works as expected except the spurious extra error
message from cellfun (which I'm going to look at).

it would still be great if someone checked whether there are important
differences between Matlab and Octave in this regard.

cheers

-- 
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