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

Regarding B::Deparse

by demerphq (Chancellor)
on Oct 19, 2001 at 19:01 UTC ( [id://120015]=perlmeditation: print w/replies, xml ) Need Help??

Hello all,

The other day I was playing around with B::Deparse and its brethren as a debugging tool with a colleague. We were using it to have a look at the bug that I posted about in Funkyness with closures.... From there we started discussing modifiers and using this code

use strict; use warnings; my $cond=1; my $i=1 for $cond; for ($cond) { my $j=1; }
(called as perl -MO=Deparse cond.pl) We got the following:
my $cond = 1; foreach $_ ($cond) { my $i = 1; } foreach $_ ($cond) { my $j = 1; }
Which is of course _wrong_. My colleague used this to supposedly _prove_ that the modifier form is identical to the non-modifier form. I disagreed but had nowhere to go until we appended the following lines to the original script and then uncommented them one at a time. Guess which ones fail
#comments added on update #print "$i/n"; # Works for input code, not output code #print "$j/n"; # Fails for both
Begin Update
I should have been more specific. The point here is the original two loops have different scoping effects. But, I presume because the output of deparse is from a stage after these effects are determined. I dont know and I'd like to understand it better. End Update

Anyway, there are some funky modules under the B branch that are worth having a look at. Id be interested as to how the other monks out the find them usefull (or not) and what tricks and tips (like the above) there are to know.

To be honest any thoughts or comments at all about this stuff would be very welcome. And while I'm trawling the communal wisdom, any thought on using -d under NT would be apreciated as well.

Somewhat incoherent post, sorry...

Yves
--
You are not ready to use symrefs unless you already know why they are bad. -- tadmc (CLPM)

Replies are listed 'Best First'.
Re: Regarding B::Deparse
by chromatic (Archbishop) on Oct 19, 2001 at 23:50 UTC
    Looking at the Perl lexer, they appear to be the same. Sorry. :)

    B::Deparse has has some major work done recently. I believe 5.6.1 was released somewhere around patch 9500. I get the same results with the latest version.

    The B::* family is still a scary bunch of code, though. You might like B::Generate, which is a nifty solution in search of a problem. :)

    Update: demerphq pointed out that the important thing under consideration is the *scope* of the variables. There is indeed scary magic in the Perl lexer between these two types. I missed the point, and apologize for any confusion.

    (There, that ought to clear up that Guru on a Mountain illusion in the rest of you. :)

      (There, that ought to clear up that Guru on a Mountain illusion in the rest of you. :)

      Nope. Not in the slightest. But you can try again later.

      :-)

      Yves
      --
      You are not ready to use symrefs unless you already know why they are bad. -- tadmc (CLPM)

Re: Regarding B::Deparse
by jackdied (Monk) on Oct 19, 2001 at 19:16 UTC
    Be very careful declaring scoped variables in conditionals. In this case, I'd consider the 'for $cond' just as dangerous as 'if $cond'

    I've never been able to figure out the rules exactly, but conditional my variables tend to fail in the most bizzare ways. I think B::Deparse is showing you how perl actually unravels that loop, which is also how it should be unraveling it.

    Changing

    my $i = 1 for $cond;
    to
    my $i; $i = 1 for $cond;
    Should give you the behavior you want.

    -jackdied

      I agree totally. This was a 'far out there' example that I knew had strange funkyness associated with it.

      Personally I think my declarations on the left side of a modifier should result in warnings under warnings, and absolutely my decls on the left side of loop modifiers should produce fatal exception under strict.

      Yves
      --
      You are not ready to use symrefs unless you already know why they are bad. -- tadmc (CLPM)

Re: Regarding B::Deparse
by blakem (Monsignor) on Oct 19, 2001 at 21:26 UTC
    Although its not the most helpful case, It Came From the Crypt! doesn't seem to run properly after passing through B::Deparse. Since it's obfu, I haven't tracked down exactly why it is failing, but you might be interested enough to dig through it....

    theorbtwo was (i believe) the one who originally noticed this.

    -Blake


      That was interesting,

      It turns out that B::Deparse was putting in "\n"s into the string that was declared at the top of It Came From the Crypt. It then thought that everything would be alright if it changed the next substitution to get rid of them, except that it wasn't. If you run B::Deparse and shove the contents into a file, then to run that you need to modify the first substitution so that it does nothing to the poor "\n"s.

      #change this: $u=$q=~s/\n\s//xg && -2; #to this $u=$q=~s/\s//xg && -2;
      That seems to do it for me at least (running perl 5.6 on a redhat box). Anyone else? Also, why does Perl insert the carriage returns and then change a regex to deal with it? That seems odd...

      jynx

        Very interesting indeed. It looks like B::Deparse doesn't fully understand the magic associated with the /x regex modifier. With /x, a literal \n and the two character sequence '\n' are not actually equivalent. B::Deparse isn't making that distinction.

        Below, the second regex is the result of running the first one through B::Deparse. As this example shows, they are not the same.

        #!/usr/bin/perl -wT use strict; my $v1 = my $v2 = "abcdef"; $v1 =~ s/c d//x; # original pattern: literal \n is gobbled by /x # equivalent to the non-x: s/cd//; $v2 =~ s/c\nd//x; # deparsed version: interpolated "\n" is not touch +ed by /x # equivalent to the non-x: s/c\nd//; print "V1 = '$v1'\n"; print "V2 = '$v2'\n"; =OUTPUT V1 = 'abef' V2 = 'abcdef'

        -Blake

Re: Regarding B::Deparse
by IraTarball (Monk) on Oct 21, 2001 at 00:04 UTC
    This might be slightly off, but maybe not. I responded to a post by George_Sherston a while ago, something about Getting_Data_from_an__END__block or something. The interesting thing that came out of that was the apparent funkiness when you do something like
    my $var = $_ while (<DATA>);
    When I run this under strict with Perl 5.6.1 and I immediately print out $var I get... nothing. No errors, no values, nothing. Even though I would expect to get the last line from DATA. I noticed that when I ran your code above I had the same behavior, that is, it printed nothing. When I ran this with Devel::Peek I saw that the pIOK and IOK flags are not set on the variable, but that it has had something assigned to it at some point because when done with strings MAX has some size in there.

    Any way, the reason for this rambling is that I've never received a really definitive answer on what's going on here, except the nebulous <q\i>"Huh, must be some bug" I got from the comp.lang.perl.moderated list. I looked briefly in the bug list and didn't see anything like this, but I'm a bit new to internals so I easily could've missed it.

    I guess I'm just wondering if this is connected to the odd closure behavior or perhaps has something to do with why the decompiled code looks like it does (because that's sorta the way it behaves, though not really).

    I hope this wasn't too incoherent and random.

    Ira,

    "So... What do all these little arrows mean?"
    ~unknown

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (4)
As of 2024-04-24 12:16 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found