Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine

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 (Bishop) 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 (Chancellor) 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 all is quiet...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (10)
As of 2018-07-20 14:58 GMT
Find Nodes?
    Voting Booth?
    It has been suggested to rename Perl 6 in order to boost its marketing potential. Which name would you prefer?

    Results (435 votes). Check out past polls.