Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

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?
!update
Mr LanX thank you very much for provided answers.
the answers are:
${shift()}+=2
${+shift}+=2
though I'm going to google what that "+" stuff exactly does.

Comment on shift implicit dereference
Download Code
Re: shift implicit dereference
by LanX (Canon) 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

    update

    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 (Abbot) 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}; }

    Output:

    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

      thank you sir, your comment was really helpful.

      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

        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)

        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

Re: shift implicit dereference (explicit)
by tye (Cardinal) on Oct 07, 2013 at 13:54 UTC

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

    - tye        

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (9)
As of 2014-09-18 15:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (116 votes), past polls