Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: shift implicit dereference

by kcott (Abbot)
on Oct 06, 2013 at 17:39 UTC ( #1057173=note: print w/ replies, xml ) Need Help??


in reply to shift implicit dereference

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


Comment on Re: shift implicit dereference
Select or Download Code
Re^2: shift implicit dereference
by Lennotoecom (Pilgrim) on Oct 06, 2013 at 17:45 UTC
    thank you sir, your comment was really helpful.
Re^2: shift implicit dereference
by tobyink (Abbot) on Oct 06, 2013 at 18:45 UTC

    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)

        Confirmed, same result with 5.10.1 on my shared hosting account.

        $ ./monktest.pl $VAR1 = { 'MONIKER' => 'Monica' }; $VAR2 = { 'MONIKER' => 'Monica' }; $ perl -v This is perl, v5.10.1 (*) built for x86_64-linux-thread-multi
        On time, cheap, compliant with final specs. Pick two.

      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

        or maybe putting in parens is more obvious?

        DB<117> use constant MONIKER =>"name" DB<118> %hash1 = ( (MONIKER) => 'Monica' ); => ("name", "Monica") DB<119> $hash1{ (MONIKER) } => "Monica" DB<142> [map { my $y = uc; ({$y => 1}) } "a".."c"] => [{ A => 1 }, { B => 1 }, { C => 1 }] DB<143> print ((1==0) ? "true" : "false") => 1 false DB<144> sub tst { ${ (shift) } } DB<145> tst \"a" => "a"

        Cheers Rolf

        ( addicted to the Perl Programming Language)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1057173]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2015-07-06 04:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (70 votes), past polls