Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer

shift implicit dereference

by Lennotoecom (Pilgrim)
on Oct 06, 2013 at 13:23 UTC ( #1057145=perlquestion: print w/ replies, xml ) Need Help??
Lennotoecom has asked for the wisdom of the Perl Monks concerning the following question:

Hi, please advice me on implicit dereference of the shift if it is possible.
$a = 5; $add2= sub{ $b = shift; $$b+=2;}; &$add2(\$a);
-this works just fine, but is there any chance to dereference it somehow as ${$shift}+=2; ? without interim variable?
Mr LanX thank you very much for provided answers.
the answers are:
though I'm going to google what that "+" stuff exactly does.

Replies are listed 'Best First'.
Re: shift implicit dereference
by LanX (Chancellor) on Oct 06, 2013 at 13:39 UTC
    if you don't really need references use aliasing ¹!

    DB<122> $a => 5 DB<123> sub alias_add { $_[0]+=2 } DB<124> alias_add $a => 7 DB<125> $a => 7

    But to fully answer the original question:

    DB<126> sub ref_add { ${ shift() }+=2 } DB<127> ref_add \$a => 9 DB<128> $a => 9 DB<129> sub ref_add2 { ${ +shift }+=2 } DB<130> ref_add \$a => 11 DB<131> $a => 11


    or using parens

    DB<102> $a=11 => 11 DB<103> sub ref_add3 { ${ (shift) }+=2 } DB<104> ref_add3 \$a; $a => 13

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    1) from perlsub:

    Any arguments passed in show up in the array @_. Therefore, if + you called a function with two arguments, those would be stored in +$_[0] and $_[1]. The array @_ is a local array, but its elements are + aliases for the actual scalar parameters. In particular, if an element + $_[0] is updated, the corresponding argument is updated (or an error +occurs if it is not updatable).
Re: shift implicit dereference
by kcott (Canon) on Oct 06, 2013 at 17:39 UTC

    G'day Lennotoecom,

    "... what that "+" stuff exactly does."

    A unary "+" is used for disambiguation. If you were to code ${shift}, that would be ambiguous: did you mean the variable $shift or a dereferencing operation on the value shifted off @_. Using a "+" indicates you meant the shift function and not a variable name. Consider this code:

    #!/usr/bin/env perl -l use strict; use warnings; my $shift = 'E'; my @x = \ (qw{A B C D}); test_shift(@x); sub test_shift { print ${+shift}; print ${shift()}; print ${shift @_}; print ${shift(@_)}; print ${shift}; }


    Ambiguous use of ${shift} resolved to $shift at ./junk line 15. A B C D E

    You'll find this usage of "+" cropping up in many places. Here's some examples.

    Does the "(" following a function name start a list of arguments to the function?

    $ perl -Mstrict -Mwarnings -le 'print (1==0) ? "true" : "false"' print (...) interpreted as function at -e line 1. Useless use of a constant ("true") in void context at -e line 1. Useless use of a constant ("false") in void context at -e line 1. $ perl -Mstrict -Mwarnings -le 'print +(1==0) ? "true" : "false"' false

    Is "{...}" an anonymous block or a hashref constructor?

    $ perl -Mstrict -Mwarnings -MData::Dump -e 'dd [map { my $y = uc; {$y +=> 1} } "a".."c"]' ["A", 1, "B", 1, "C", 1] $ perl -Mstrict -Mwarnings -MData::Dump -e 'dd [map { my $y = uc; +{$y + => 1} } "a".."c"]' [{ A => 1 }, { B => 1 }, { C => 1 }]

    How can I tell a constant bareword and a hash key bareword apart?

    $ perl -Mstrict -Mwarnings -le 'use constant X => "a"; my %h = (a => 1 +); print $h{X}' Use of uninitialized value in print at -e line 1. $ perl -Mstrict -Mwarnings -le 'use constant X => "a"; my %h = (a => 1 +); print $h{+X}' 1

    Documentation for unary "+" usages appears to be rather scattered. For the three pairs of examples above, see "perlop: Symbolic Unary Operators", "perlref: Making References" and "constant: CAVEATS", respectively. There are other examples documented elsewhere. I couldn't locate any references to the ${+shift} example.

    -- Ken

      Another place a unary plus is often useful is to protect against the effects of the fat comma:

      use constant MONIKER => 'name'; my %hash1 = ( +MONIKER => 'Monica' ); # compared with... my %hash2 = ( MONIKER => 'Monica' ); use Data::Dumper; print Dumper(\%hash1, \%hash2);
      use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

        I get the same results as Sören. I'm using v5.18.1 (darwin-thread-multi-2level).

        (MONIKER() => 'Monica') produces 'name' => 'Monica' in the Dumper output.

        -- Ken

        That's looking very nice but...

        $VAR1 = { 'MONIKER' => 'Monica' }; $VAR2 = { 'MONIKER' => 'Monica' }; $ perl -v This is perl 5, version 14, subversion 2 (v5.14.2) built for i686-linu +x-gnu-thread-multi-64int ...

        Cheers, Sören

        Créateur des bugs mobiles - let loose once, run everywhere.
        (hooked on the Perl Programming language)

      thank you sir, your comment was really helpful.
Re: shift implicit dereference (explicit)
by tye (Sage) on Oct 07, 2013 at 13:54 UTC

    shift @_ is clearer than +shift or shift().

    - tye        

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1057145]
Front-paged by Corion
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (3)
As of 2016-07-31 09:47 GMT
Find Nodes?
    Voting Booth?
    What is your favorite alternate name for a (specific) keyboard key?

    Results (269 votes). Check out past polls.