http://www.perlmonks.org?node_id=1061308

std3rr has asked for the wisdom of the Perl Monks concerning the following question:

Hi!

I used to use the Want module to check if Im in the middle or at the last of chain of autoloaded methods. Then I realized it did'nt work under threads.

Is there any other way to find out if Im on a tail-method?

example:

use strict; package FOO { use Want; sub AUTOLOAD { print "@{[our $AUTOLOAD]}\n"; print " ..and Im a tail!\n" if not want "OBJECT"; return $_[0] || bless {}; } } FOO->funky->node->blaah;

With want() I used to test for "OBJECT", but as it fails under threads, I wonder if there are any neat and maybe simpler alternatives?

Replies are listed 'Best First'.
Re: Finding the end of a method-chain
by Eily (Monsignor) on Nov 06, 2013 at 13:43 UTC

    it fails under threads
    How so? I didn't see anything about threads in the documentation of Want.

    You probably already know that, but just in case I'll say it anyway: in your exemple, there is no object created, since the first parameter passed to funky is actually "FOO" (and so on to every following method). In the end, your autoload sub only returns a new object if you call it in a way that does not look object oriented (without the -> operator).

    And last thing, instead of if not you can use unless

      Hello Eily!

      You'll get segmentation fault. Just try:
      perl -Mthreads -MWant -e 'threads->create(sub{want("OBJECT")})->join'

      ... you know what? ..You're right! I did'nt realize that I just passed "FOO". :)
      It was a bad example.
      You could actually remove the bless totaly and It will still work. Anyway, the output is still as expected. The example and the want condition, works. I guess its because Want recognize it as wanting a "OBJECT" as we refer to the methods with '->'.

      The Want module is wonderfull and does what I want, but I could'nt get around the segfault under threads.

      So I still wonder if this particular finding-the-chain-tail can be done threadsafe or maybe in any other fashion? :)

        Alright, I should have seen that, or at least tried it. The problem is that create is called before join (obviously) so the way the return of join will be used is unknown at that time. threads allows you to indicate in which context you want your sub to be called (void, scalar or list) (and if you didn't know that, you probably always called your sub in a scalar context), but not to indicate what will be done of the returned value(s).

        Unless the sub passed as a parameter to threads->create can be your tail method, you could just check (caller 1)[3] eq '(eval)' before trying to use want.

        If this sub can be your tail method, be sure to add {'void' => 1} as the first parameter to threads->create when you're not going to use the return of join(). Then you could have: print " ..and Im a tail!\n" unless defined wantarray and want "OBJECT"

        This is probably a bad idea if you want to be able to use the return value of your method, which can be called by thread->create, and can be the tail method. Why are trying to do that by the way? Maybe you've just set foot on a XY Problem and could avoid using want altogether.

Re: Finding the end of a method-chain
by DrHyde (Prior) on Nov 11, 2013 at 11:31 UTC
    I'd never heard of Want.pm before, thankyou for bringing this example of The Right Sort Of Mad to my attention!