Perl hangs when returning lvalue closure from another lvalue closure

Discussion in 'Perl Misc' started by Julian Mehnle, Jul 17, 2003.

  1. Hi all,

    I'm having a serious problem that using lvalue closures in a Perl class
    module causes Perl to hang. I have wasted days on researching the problem,
    but could not find a solution. I think it might be a bug in Perl; I'm using
    5.8.0, but can reproduce the behavior on 5.6.1 as well.

    I failed to trim the scenario down to a pure sample program to demonstrate
    the bug, so I have to present you the whole thing (it's not that big,
    though):

    http://files.mehnle.net/tmp/perl-lvalue-closures/ -- or: --
    http://files.mehnle.net/tmp/perl-lvalue-closures.tar.gz

    To execute the scenario, call "test.pl".

    The core is DBIx::Class, which is meant to transparently implement object
    persistency. USM::Class and USM::User are exemplary classes that are
    derived from DBIx::Class like this:

    DBIx::Class <-- USM::Class <-- USM::User

    Every class shall be able to have inheritable, overrideable class (not
    instance) fields, so I used the same mechanism Class::Data::Inheritable
    uses: For every class field, create a closure with its own field storage
    variable. If the closure is called from a derived class to modify the field
    value, it creates a new closure in the namespace of the derived class with
    its own field storage variable. It's supposed to work like this:

    DBIx::Class->foo('nil');
    # DBIx::Class->foo eq 'nil'
    # USM::Class->foo eq 'nil'
    USM::Class->foo('zippo');
    # DBIx::Class->foo eq 'nil'
    # USM::Class->foo eq 'zippo'

    Now I wanted to be clever and make these closures into lvalue subs to allow
    code like

    DBIx::Class->foo = 'nil';
    USM::Class->foo = 'zippo';

    See the class field accessor closure created by the _create_class_field sub
    in DBIx/Class.pm:

    253: my $accessor = sub :lvalue {
    254: my $want_class = shift();
    255: $want_class->_class_only();
    256:
    257: no strict 'refs';
    258:
    259: # Is field to be modified, and doesn't sub-class already have its
    # own accessor?
    260: if (@_ and ($want_class ne $class)) {
    261: # Create an accessor for sub-class, and return its $value as
    # an lvalue:
    262: # $want_class->_create_class_field($field)->($want_class, @_);
    263: my $acc = $want_class->_create_class_field($field);
    264: $acc->($want_class, @_);
    265: # $value; # DEBUG, this doesn't belong here!
    266: }
    267: else {
    268: # We are a closure, so _create_class_field()'s $value is used
    269: # for the field's storage:
    270: $value = shift() if @_;
    271: # Return $value as an lvalue:
    272: $value;
    273: }
    274: };

    To make a long story short, Perl hangs in in line 264, when calling the
    newly created accessor closure. If I insert a dummy lvalue after that call,
    like in line 265, then Perl does NOT hang, and returns from both the old and
    the newly created accessor successfully, although of course the wrong lvalue
    is then returned from the old accessor.

    Perl seems to hang in some kind of internal endless loop (100% CPU load),
    `strace` shows no more syscalls during the hang. Perl only terminates if I
    press <CTRL+C> eventually.

    I also tried debugging the thing in the Perl debugger, see "debug.log" for a
    debugger session log. Interestingly, manually performing the
    `$acc->($want_class, @_)` call (via the `x` debugger command when the
    debugger is in line 264) works. Though, as soon as the debugger does the
    call from the module's code, it hangs again.

    So all things considered, I guess the problem has to do with how Perl
    returns lvalues from lvalue subs. Any ideas?

    --
    Julian Mehnle.
     
    Julian Mehnle, Jul 17, 2003
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. omission9
    Replies:
    3
    Views:
    370
    omission9
    Feb 25, 2004
  2. Kavya
    Replies:
    9
    Views:
    541
    Dik T. Winter
    Oct 28, 2006
  3. Steven W. Orr

    Another dumb scope question for a closure.

    Steven W. Orr, Jan 9, 2008, in forum: Python
    Replies:
    2
    Views:
    248
    Waldemar Osuch
    Jan 9, 2008
  4. Replies:
    11
    Views:
    715
    James Kuyper
    Sep 22, 2008
  5. Tim Shadel

    Gem hangs => TCPSocket.write hangs

    Tim Shadel, Jul 23, 2005, in forum: Ruby
    Replies:
    1
    Views:
    422
    Ville Mattila
    Jul 24, 2005
Loading...

Share This Page