octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: cellfun calling style


From: John W. Eaton
Subject: Re: cellfun calling style
Date: Wed, 21 Sep 2011 15:38:42 -0400

On 20-Sep-2011, John W. Eaton wrote:

| On 20-Sep-2011, Jordi Gutiérrez Hermoso wrote:
| 
| | On 20 September 2011 14:54, John W. Eaton <address@hidden> wrote:
| | > On 20-Sep-2011, Rik wrote:
| | 
| | > | octave_value f = symbol_table::find_function (func.function_value ()
| | > |                                                          -> name ());
| | >
| | > We probably don't want to do that because I think it will screw up
| | > cases where people actually do want to use the function handle for
| | > purposes of finding the right overloaded function to call.
| | 
| | Isn't that what I did here?
| | 
| |     
http://hg.savannah.gnu.org/hgweb/octave/annotate/9b8e786bbf3c/src/DLD-FUNCTIONS/cellfun.cc#l357
| 
| I think that's OK if the is_overloaded function is always giving
| you the correct result.
| 
| I'll be able to say more when I am able to come up with a simple
| example that demonstrates the bug I've found.

OK, here is what I can say now.  The code is small, so I'm inserting
it all here, but it is also attached in the tar file for easy
extraction and experimentation if anyone is interested.

First, I have two classes, one derived from the other.  These are the
constructors.  The parent class overloads the numel function.

  ------------------
  @derived/derived.m
  ------------------

  function r = derived (n)
    s.a = n;
    p = parent (n);
    r = class (s, 'derived', p);
  end

  ----------------
  @parent/parent.m
  ----------------

  function r = parent (n)
    s.a = rand (n, 1);
    r = class (s, 'parent');
  end

  ---------------
  @parent/numel.m
  ---------------

  function r = numel (x, varargin)
    disp ('in @parent/numel.m');
    r = numel (x.a, varargin{:});
  end

Now I have another class, which is not derived from anything, but
contains an object of type "derived" as it's only member:

  ------------
  @test/test.m
  ------------

  function r = test (n)
    s.d = derived (n);
    r = class (s, 'test');
  end

This class also has a member function that is supposed to return the
number of elements in the member variable d.  There are several ways
to do this job and only one of the three below works in Octave

  ------------------
  @test/samplesize.m
  ------------------

  function [r1, r2, r3] = samplesize (x)

    % This works in Matlab, but in Octave numel is always returning 1.
    % Apparently it is not finding the overloaded @parent/numel
    % function.
    r1 = cellfun (@numel, {x.d});

    try
      % This works in Matlab but fails with an error in Octave because
      % object indexing doesn't seem to work in the anonymous function
      % context.
      r2 = arrayfun (@(i) numel (x(i).d), 1:numel(x), 'uniformoutput', true);
    catch
      fprintf ('arrayfun failed: %s\n', lasterror.message);
      r2 = -1;
    end

    % The following works in both Octave and Matlab.
    n = numel (x);
    r3 = zeros (1, n);
    for i = 1:n
      r3(i) = numel (x(i).d);
    end

  end

Finally, here is a script to run to construct some objects and call
the samplesize function.

  ------
  doit.m
  ------

  x(1) = test (13);
  x(2) = test (42);

  try
    % This also works in Matlab:
    x = [test(13), test(42)];
  catch
    disp ('object concatenation failed')
  end

  disp ('calling samplesize');

  [r1, r2, r3] = samplesize (x)

I see now that the cellfun call will work if I add the function

  ----------------
  @derived/numel.m
  ----------------

  function r = numel (x, varargin)
    disp ('in @parent/numel.m');
    r = numel (x.a, varargin{:});
  end

but Octave should be finding the overloaded function in the parent
class.  So I guess we need to work a little harder at finding methods
for derived classes.

As I said, I'm working on this bug, and now that I think I understand
the reason for the failure, I hope to have a fix soon.

jwe

Attachment: classbug.tar.gz
Description: Binary data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]