Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

warnings under the debugger

by trwww (Priest)
on Mar 08, 2007 at 08:18 UTC ( [id://603781]=perlquestion: print w/replies, xml ) Need Help??

trwww has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,

I'm curious as to why I see warnings under one context but not the other.

In other words, why does this sequence show a warning:

$ perl -Mwarnings -Mstrict -e 'my $bar = { foo => () }' Odd number of elements in anonymous hash at -e line 1.

While in the debugger, a similar construct does not emit a warning:

$ perl -Mwarnings -Mstrict -de 1 Loading DB routines from perl5db.pl version 1.27 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(-e:1): 1 DB<1> x { foo => () } 0 HASH(0x9c5b8f8) 'foo' => undef DB<2> q

?

If someone could point me to the relevant documentation or explain this behavior I'll... buy you a drink of your choice :-)

Thanks!

Replies are listed 'Best First'.
Re: warnings under the debugger
by almut (Canon) on Mar 08, 2007 at 12:42 UTC

    I suppose it has to do with the scoping of the warnings module, which is block scoped (i.e. scoped to the "main" program in your case, which is just "1"). Apparently, the x ("evaluate and print expression") command of the debugger is executed in a different block/scope - at least that's my first guess without having looked too deeply into the issue...

    If you use the globally scoped -w in place of -Mwarnings, you do get warnings even for x in the debugger, because you then get warnings everywhere (which might be more than you wanted to know, however...)

    $ perl -w -Mstrict -de 1 Loading DB routines from perl5db.pl version 1.28 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(-e:1): 1 DB<1> x { foo => () } Odd number of elements in anonymous hash at (eval 5)[/usr/lib/perl5/5. +8.8/perl5db.pl:628] line 2. at (eval 5)[/usr/lib/perl5/5.8.8/perl5db.pl:628] line 2 eval '($@, $!, $^E, $,, $/, $\\, $^W) = @saved;package main; $ +^D = $^D | $DB::db_stop; { foo => () }; ;' called at /usr/lib/perl5/5.8.8/perl5db.pl line 628 DB::eval called at /usr/lib/perl5/5.8.8/perl5db.pl line 3412 DB::DB called at -e line 1 0 HASH(0x65f420) 'foo' => undef

    I doubt that this observation is sufficient to entitle me for a free drink of my choice - but anyway. :)

Re: warnings under the debugger
by virtualsue (Vicar) on Mar 08, 2007 at 09:31 UTC
    If you put your one-liner into a file, then run that under the debugger, the warning is emitted.

    $ perl -d it.pl Default die handler restored. Loading DB routines from perl5db.pl version 1.07 Editor support available. Enter h or `h h' for help, or `man perldebug' for more help. main::(it.pl:6): my $bar = { foo => () }; DB<1> s Odd number of elements in hash assignment at it.pl line 6. Debugged program terminated. Use q to quit or R to restart, use O inhibit_exit to avoid stopping after program termination, h q, h R or h O to get additional info. DB<1>
    I have no explanation. I don't tend to use the debugger very often, and when I do, I wouldn't use it for just one line of code. I do sometimes use B::Deparse to deconstruct a snippet of code:
    perl -MO=Deparse it.pl my $bar = {'foo', ()}; it.pl syntax OK
    Is that more in line with what you really wanted?
Re: warnings under the debugger
by GrandFather (Saint) on Mar 08, 2007 at 08:51 UTC

    In the first case () is in scalar context so is a pair of empty brackets, not the empty list you may have been expecting. There is no error because => is really just a comma that implictly quotes the bare word to the left. The anon hash is thus the equivelent of {'foo', }. (See List value constructors and Comma Operator.)

    Why you get different behaviour in the debugger I don't know however.

    Update: strike bogus scalar context comment - see reply.


    DWIM is Perl's answer to Gödel
      In both cases the the anonymous hash constructor { foo => () } evaluates its contents in array context.

      On the other hand, I don't see how context would even matter. Either way, foo => () represents a single element, and { scalar( foo => ()) } warns just the same.

      Why the debugger doesn't warn I don't know either.

      Anno

Re: warnings under the debugger
by Moron (Curate) on Mar 08, 2007 at 14:13 UTC
    Could it be because the debugger evals its input rather than submitting directly to Perl?

    Update: ... and notwithstanding the, erm, confident reply below, I can now suggest this demo:

    unixhost> # case 1 without eval unixhost> perl -ew '$foo = { bar => () };' Name "main::foo" used only once: possible typo at -e line 2. Odd number of elements in hash assignment at -e line 2. unixhost> unixhost> # case 2 - now "protect it" with eval ... unixhost> perl -ew 'eval "$foo = { bar => () };";' unixhost> unixhost> # nothing!

    -M

    Free your mind

      unixhost> perl -ew 'eval "$foo = { bar => () };";'

      If I use -we instead of -ew, I do get the warnings with eval, too...

      $ perl -we 'eval "$foo = { bar => () };";' Name "main::foo" used only once: possible typo at -e line 1. Use of uninitialized value in concatenation (.) or string at -e line 1 +.

      (I figure that with -ew, the program is just the bareword "w", which is being passed the rest of the commandline as arguments :)

      Therefore I am still suggesting that an explanation for the symptoms is that, to use Anno's words, the debugger "starts a new interpreter each time ..." ... it reads the keyboard input and uses "string eval" on it instead of submitting it directly to Perl.

      -M

      Free your mind

        When I tried it (I don't use the debugger normally), I found that the warning is shown, if warnings are switched on. Here is a (slightly edited) session:
        anno@oliva> perl -wd -e '' Loading DB routines from perl5db.pl version 1.28 [...] DB<1> $x = { 1 } Odd number of elements in anonymous hash at (eval 10)[/usr/local/lib/p +erl5/5.8.7/perl5db.pl:628] line 2. [...]
        So it seems the debugger has ways of restoring the warning state of the outer interpreter in an eval. (Can't be that hard). Why the original poster didn't see the warning remains an open question.

        Anno

      Well, that's string eval, which starts a new interpreter with warnings switched off to begin with. Technically you are correct, string eval has a radical effect on warnings :)

      What I meant to say is that a warning that is generated inside an eval (of any type) will be shown. Warnings are not suppressed by eval in a similar way die is.

      perl -we 'eval "use warnings; $foo = { bar => () };";
      will print the warning, even from within eval.

      Anno

      eval has no effect on warnings.

      Anno

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://603781]
Approved by graq
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (5)
As of 2024-04-25 19:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found