Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

wantarray propagation?

by Anonymous Monk
on May 20, 2011 at 19:54 UTC ( [id://905960]=perlquestion: print w/replies, xml ) Need Help??

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

Perhaps I am misunderstanding the basic usage of wantarray, but it seems that the void/scalar/list context of a subroutine call propagates to sub-subroutine calls. Is there any way to avoid this, or to force a subroutine call to be executed in void context? For example, consider this code:

sub test { unless (defined wantarray) { print "test: wantarray is undefined\n"; } elsif (wantarray) { print "test: wantarray is true\n"; } else { print "test: wantarray is false\n"; } } sub test2 { test(); } my @t = test2();

Executing this prints the statement "test: wantarray is true". However, I would like a way to call test() from within test2(), and force void context. Is this possible?

Replies are listed 'Best First'.
Re: wantarray propagation?
by kennethk (Abbot) on May 20, 2011 at 19:58 UTC
    From return:
    In the absence of an explicit return, a subroutine, eval, or do FILE automatically returns the value of the last expression evaluated.
    So, since you do not have an explicit return in test2, your code is equivalent to

    sub test2 { return test(); }

    and hence the propagation. If you want it evaluated in a certain context, then evaluate it in that context, perhaps as

    sub test2 { test(); return; }
Re: wantarray propagation?
by John M. Dlugosz (Monsignor) on May 20, 2011 at 19:58 UTC
    Indeed. You can use scalar foo(...) to force foo to be called in scalar context. I think using the function on a line by itself, without using the return value, will give void context. The reason it is not the case in your example is because test() is the last line in the function test2, and is an implicit return statement. You are actually saying return test() which propagates test2's context. Write test(); return; instead.

Re: wantarray propagation?
by ikegami (Patriarch) on May 20, 2011 at 20:34 UTC

    There's no need to force anything. If you fixed test2 so it returned a list like it should, test wouldn't be evaluated in the same context as test2.

    sub test { unless (defined wantarray) { print "test: wantarray is undefined\n"; } elsif (wantarray) { print "test: wantarray is true\n"; } else { print "test: wantarray is false\n"; } } sub test2 { test(); # undefined return ...[ stuff to put in @t ]...; } my @t = test2();

    If you want the technical but ultimately useless details, see kennethk's post.

Re: wantarray propagation?
by Khen1950fx (Canon) on May 21, 2011 at 04:29 UTC
    You can force VOID context by using Gives. You can also get greater control of wantarray by using Want. Here's what I did:
    #!/usr/bin/perl use strict; use warnings; use Gives; use Want 'want'; sub test : Gives( @Contexts ) { if (defined want('VOID')) { print "test: wantarray is undefined\n"; } elsif (want('SCALAR')) { print "test: wantarray is true\n"; } else { print "test: wantarray is false\n"; } } sub test2 { test(); } print test2;

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (7)
As of 2024-04-19 13:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found