Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Overwrite built-in wantarray()

by Tobiwan (Beadle)
on Aug 20, 2007 at 21:34 UTC ( [id://633947]=perlquestion: print w/replies, xml ) Need Help??

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

Hi there, I want to "decorate" perls built-in wantarray-function, but I can't find a way to do that. I want to do something like this:
my $class = 'MyClass'; *CORE::GLOBAL::wantarray = sub { return CORE::wantarray(@_) if(!${"$class\::PRETEND_CONTEXT"}); return 1 if(${"$class\::PRETEND_CONTEXT"} == 3); return 0 if(${"$class\::PRETEND_CONTEXT"} == 2); return undef if(${"$class\::PRETEND_CONTEXT"} == 1); };
But, not as for the build-in function caller(), this doesn't work and it throws the following error:
Bareword found where operator expected at /usr/lib/perl/5.8/Data/Dumpe +r.pm line 267, near "$realtype = $realpack ? Scalar::Util::reftype" (Might be a runaway multi-line ?? string starting on line 237) (Missing operator before Scalar::Util::reftype?)
It seems to be, that wantarray isn't in CORE. But where it is? If I only redefine the function (in CORE::GLOBAL::) without calling the original function, all is ok. But I don't want that. How can I decorate it? Any suggestions? Tobiwan PS: if you want to try the code-snippet, you have to put it into the "import()" function of a class and you have to "use TheClass;". There is a write protection for the CORE:: Classes.

Replies are listed 'Best First'.
Re: Overwrite built-in wantarray()
by merlyn (Sage) on Aug 21, 2007 at 00:03 UTC
    Why are you trying to fake the context? What will that gain you? It's not like you can cheat a routine to return a different thing in an "incorrect" context. It simply won't make sense.

    If you need to pass out-of-band information between cooperating routines, you can always use a localized package variable.

      I want to fake the context for tests. I want to do something like this
      FakeContext('void'); my @response = tested_sub(); is(scalar(@response), 0, 'void return'); FakeContext('scalar'); my @response = tested_sub(); is(scalar(@response), 1, 'scalar return');
      I only want to fake the context for this one sub-call. All contexts in calls in this tested_sub() should be real and unmodified. When I overwrite the caller() function and change the wantarray-flag, this doesn't have any effect for wantarray().

      And I've to decorate ist, because when I overwrite it complete, I can't fake only the first level of my sub-call.

      The only (not really god) idea I've is, to overwrite the wantarray() and use caller() to read out the context. But I think this will cause stragne side-effects.

      Any ideas? With PadWalker or Devel::Caller I can read out many things, but can I change the context? I don't know (yet).

      PS: with CORE::GLOBAL::wantarray I can overwrite the function, but I can't get any referene to the original sub.

        Ewww. Why not just:
        tested_sub(); ok(some side effect, "expected side effect"); my $scalar_response = tested_sub(); is($scalar_response, $expected, "gives proper scalar value"); my @list_response = tested_sub(); is_deeply(\@list_response,\@expected_response, "gives proper list valu +e");
        Don't be trying to freak Perl out. I'd never expect the right response from giving it the wrong context. That's just asking for hurt.
Re: Overwrite built-in wantarray()
by chromatic (Archbishop) on Aug 20, 2007 at 22:48 UTC

    It looks unoverrideable to me:

    my $p = prototype 'wantarray'; print defined $p ? $p : "(not overrideable)";

      I think the conclusion is correct, though the test is not done properly ;) — the function name argument to prototype should've been prefixed with CORE::.

      Compare the results using a function that is overrideable, like open

      for my $func qw(CORE::open open) { my $p = prototype $func; print "$func: ", defined $p ? $p : "(not overrideable)", "\n"; }

      Output:

      CORE::open: *;$@ open: (not overrideable)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://633947]
Approved by calin
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (3)
As of 2024-04-16 15:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found