Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Scalar followed by parenthetical...

by Anonymous Monk
on May 19, 2013 at 02:15 UTC ( #1034178=perlquestion: print w/ replies, xml ) Need Help??
Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Why doesn't the following produce an error??
#!/usr/bin/perl use warnings; use strict; use Data::Dumper; my @h = ( { A => 1, B => undef }, { A => 2, B => 2 }, { A => 2, B => undef }, ); $_->{B} ||= $_{A} foreach @h; # Bug! print Dumper(\@h);

Comment on Scalar followed by parenthetical...
Download Code
Re: Scalar followed by parenthetical...
by LanX (Canon) on May 19, 2013 at 02:42 UTC
    $_{A} tries to access the %_ hash and not a "Scalar followed by parenthetical" ...

    DB<126> $_{A}=42 => 42 DB<127> \%_ => { A => 42 }

    ... which seems to be a predeclared global like $a.

    Check special vars.

    ...

    Couldn't find it in perlvar, but I assume the symbol _ has a special "freedom" in Perl.

    I.a.w. @_ and $_ are extending their magic to %_! 1

    • Maybe it's just reserved for future use ...

    • Maybe just badly/non documented goody for map constructs...

    • Maybe it's an old bug nobody at P5P dares to fix... (there might be dragons ;-)

    I think you will have to learn to live with it... =)

    Cheers Rolf

    ( addicted to the Perl Programming Language)

    UPDATES

    added code

    footnotes

    1) see solution

      ...maybe it's a side-effect of how those specially named variables are vivified. Oh, and strike that "maybe" :)

        It is. The way the punctuation variables are implemented, if $X exists (assuming X is a punctuation character), then @X and %X also exist.

        There are one or two CPAN modules that make use of the magic global %_. MooseX::Params is an example.

        With a bit of digging around in perlvar you can figure out plenty of spare global variables. I use them occasionally in local code (%\ is one of my favourites), but have so far resisted the urge to publish anything using them. Global variables don't usually make for very good reusable code.

        package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
Re: Scalar followed by parenthetical...
by BrowserUk (Pope) on May 19, 2013 at 02:48 UTC

    Not a bug. As $_{A} (did you mean $_->{A} perchance?), is undef, all hash keys 'B' that have a non-true value are (re)set to undef:

    C:\test>junk Use of uninitialized value $_{"A"} in concatenation (.) or string at C +:\test\junk.pl line 13. $_{A} ::=> $VAR1 = [ { 'A' => 1, 'B' => undef }, { 'A' => 2, 'B' => 2 }, { 'A' => 2, 'B' => undef } ];

    Might have expected a warning though?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      > Not a bug.

      > Might have expected a warning though?

      Since the OP's code uses strict it should die with

      Global symbol "%_" requires explicit package name at ... Execution of ... aborted due to compilation errors.

      Cheers Rolf

      ( addicted to the Perl Programming Language)

        But isn't %_ immune to strict in the same way and for the same reasons as $_ and @_?

        C:\test>perl -cmstrict -E"say %_" -e syntax OK

        That is, they are all 3 a part of the same typeglob.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Scalar followed by parenthetical...
by LanX (Canon) on May 19, 2013 at 03:34 UTC
    ehm ... something completely different!

    If you meant to write:

    $_->{B} ||= $_->{A} foreach @h;

    you should be warned about another bug!

    I doubt that you really want $_->{B} to be overwritten if it's 0 or "".

    Always use defined-or // to check for undef!

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      actually I did want $_->{B} to be overwritten... just got bitten in my code where I forgot the "->" for the "A" side, but didn't see a warning. Thanks all!
        Thanks for sharing your error. I learned a lot from the explanations.
        Bill

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (7)
As of 2014-10-21 02:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (95 votes), past polls