Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
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 surveying the Monastery: (8)
As of 2015-04-25 09:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Who makes your decisions?







    Results (477 votes), past polls