tlm has asked for the wisdom of the Perl Monks concerning the following question:
Dear monks,
My faith in -MO=Deparse, a tool I've counted on for so long, has been severely tested recently. A few days ago ikegami pointed out errors in output from -MO=Deparse. Today I found what appears like another -MO=Deparse goof. Here's the original snippet and its output:
% perl -le '$_ = ($x) = (4, 5, 6); print'
3
Here is -MO=Deparse's rendition of same:
% perl -MO=Deparse,-p -le '$_ = ($x) = (4, 5, 6); print'
($_ = ($x = (4, 5, 6)));
print($_);
-e syntax OK
And, finally, here is the execution of -MO=Deparse's rendition:
% perl -le '($_ = ($x = (4, 5, 6))); print($_)'
6
I've stared at this till my eyes hurt, so I think it's time to let fresh eyes look at it at tell me what I'm missing. ('Cause I sure hope it's me and not -MO=Deparse that is wrong here).
Thanks for your help.
Addendum: For those not familiar with the whole -MO=Deparse thing the place to look for more info is B::Deparse, and also B and O.
Re: Say it isn't so, -MO=Deparse!
by ysth (Canon) on Apr 03, 2005 at 22:49 UTC
|
I'm afraid -MO=Deparse is wrong.
$x = (4, 5, 6) is a scalar assignment, assigning 6 to $x, and returning $x in scalar context.
($x) = (4, 5, 6) is a list assignment, assigning 4 to $x, and returning 3 (elements on the right) in scalar context.
FWIW, this happens for me in 5.6.2, but not in any perl 5.8.0 or greater. Update: by "this", I mean the bug where Deparse drops the () around the $x, changing what should be a list assignment into a scalar assignment. The behaviours I cite above of list and scalar assignments are correct and documented. | [reply] [d/l] [select] |
|
| [reply] |
|
$ perl -le '$_ = ($x) = (4, 5, 6); print'
3
$ perl -le '($_ = ($x = (4, 5, 6))); print($_)'
6
$ perl -MO=Deparse,-p -le '$_ = ($x) = (4, 5, 6); print'
BEGIN { $/ = "\n"; $\ = "\n"; }
($_ = (($x) = (4, 5, 6)));
print($_);
-e syntax OK
$ perl -v
This is perl, v5.8.3 built for i586-linux-thread-multi
I would like to upgrade, but this is a managed system.. | [reply] [d/l] |
|
I would like to upgrade, but this is a managed system
No need, your perl doesn't have the bug. I'm guessing you misunderstood some part of what I said above, but can't guess which part.
| [reply] |
Re: Say it isn't so, -MO=Deparse!
by cchampion (Curate) on Apr 03, 2005 at 22:55 UTC
|
Which version are you using?
Looks like you should upgrade ...
$ perl -v
This is perl, v5.8.5 built for i386-linux-thread-multi
Copyright 1987-2004, Larry Wall
[SNIP]
$ perl -le '$_ = ($x) = (4, 5, 6); print'
3
$ perl -MO=Deparse,-p -le '$_ = ($x) = (4, 5, 6); print'
BEGIN { $/ = "\n"; $\ = "\n"; }
($_ = (($x) = (4, 5, 6)));
print($_);
-e syntax OK
$ perl -MO=Deparse,-p -le '$_ = ($x) = (4, 5, 6); print' | perl
-e syntax OK
3
See also Parsing of subscript separator in B::Deparse for another Deparse case.
HTH | [reply] [d/l] |
Re: Say it isn't so, -MO=Deparse!
by rg0now (Chaplain) on Apr 04, 2005 at 10:38 UTC
|
Pustular Postulant!
I have seen many times here at PerlMonks that you pretty much favor -MO=Deparse. So it might be interesting to you that, as a first step of writing the Perl 5 to Perl 6 converter, Larry is working on parsing Perl to XML. The idea is to use the XML representation to turn it back to Perl 5 (to verify the correctness of the parser), and then to any other target languages. So it would be of similar functionality to -MO=Deparse, but it would be more correct I think.
Somehow, someone should convince Larry to release his code to let people to play around with it...
| [reply] [d/l] [select] |
Re: Say it isn't so, -MO=Deparse!
by diotalevi (Canon) on Apr 04, 2005 at 06:30 UTC
|
You know, B::Deparse makes some mostly good guesses about how to reconstitute compiled perl as source code but I don't generally take its output as gospel. Use better things like B::Concise, B::Terse, B::Debug. I highly prefer viewing Concise over most other versions when looking to see how perl compiles something. You get enough information to understand your program and you have none of the reconstitution ambiguity inherent in B::Deparse. | [reply] |
Re: Say it isn't so, -MO=Deparse!
by traveler (Parson) on Apr 03, 2005 at 22:49 UTC
|
C:\> perl -MO=Deparse,-p -le "$_ = ($x) = (4, 5, 6); print"
BEGIN { $/ = "\n"; $\ = "\n"; }
($_ = (($x) = (4, 5, 6)));
print($_);
-e syntax OK
C:\>perl -le "$_ = ($x) = (4, 5, 6); print"
3
C:\>perl -v
This is perl, v5.8.1 built for MSWin32-x86-multi-thread
(with 1 registered patch, see perl -V for more detail)
Copyright 1987-2003, Larry Wall
Binary build 807 provided by ActiveState Corp. http://www.ActiveState.
+com
ActiveState is a division of Sophos.
Built 18:19:11 Nov 3 2003
What versions are you running? | [reply] [d/l] |
Re: Say it isn't so, -MO=Deparse!
by Errto (Vicar) on Apr 03, 2005 at 22:51 UTC
|
I haven't used O before, but it sure looks like a bug in Deparse to me. In its version, the assignment to $x is a scalar assignment, but in your original version it's a list assignment. The difference is in the fact that a list assignment in scalar context returns the length of the RHS list (which is 3), whereas a scalar assignment evaluates the RHS in scalar context, and the scalar comma operator always returns its right operand, so you end up with 6.
In a nutshell, Deparse seems not to have picked up on the fact that your parentheses around the $x changed the context of the assignment, so it dropped them. Update: that last sentence is backwards. What I meant was that Deparse failed to add the extra parentheses around $x needed to signify a list assignment to a single scalar variable.
| [reply] |
Re: Say it isn't so, -MO=Deparse!
by Ultra (Hermit) on Apr 04, 2005 at 07:51 UTC
|
I am running This is perl, v5.8.5 built for i686-linux-thread-multi
The problem you saw can be reproduced here too; here's an interesting thing though:
perl -MO=Deparse,-p -e '$_ = ($x) = (4, 5, 6); print'
($_ = (($x) = (4, 5, 6)));
print($_);
-e syntax OK
And here's the output of what Deparse gave me:
perl -e '($_ = (($x) = (4, 5, 6)));print'
3#and my shell prompt here of course
Note: that I removed the -l switch
| [reply] [d/l] [select] |
|
|