polettix has asked for the wisdom of the Perl Monks concerning the following question:
Note: this has been written with 5.8.8 in mind, I don't know if it applies to other versions as well
Some days ago one guy dropped in an otherwise sleepy #perl.it and asked why something like this wasn't working properly:
What's that junk?#!/usr/bin/perl bu("a:b:c:d"); sub bu { local $" = '], ['; print "scalar: ", scalar(split(/:/, $_[0])), "\n"; print scalar(@_), "[@_]\n"; print "scalar: ", scalar(split(/:/, $_[0])), "\n"; print scalar(@_), "[@_]\n"; print "scalar: ", scalar(split(/:/, $_[0])), "\n"; print scalar(@_), "[@_]\n"; } ## end sub bu __END__ scalar: 4 4[a], [b], [c], [d] scalar: 1 1[@] scalar: 1 1[�]
(k`sOSe is the nickname of the guy, BTW.)Use of implicit split to @_ is deprecated at ksose2.pl line 8. Use of implicit split to @_ is deprecated at ksose2.pl line 10. Use of implicit split to @_ is deprecated at ksose2.pl line 12.
Oh wow, that split isn't doing its work nicely. Now the problem is, deprecation doesn't mean that something is forbidden, only that it should be avoided because it could be eliminated sometime in the future. Having junk in @_ is more likely a flag of "don't you dare to use this, otherwise Bad Things(TM) will happen".
I tried to concoct a couple of tests, and here's what I saw.
Only the second sub seems to be working properly.#!/usr/bin/perl use strict; use warnings; sub first { local $" = '], ['; print "first\n"; print "scalar: ", scalar(split(/:/, $_[0])), "\n"; print scalar(@_), " item(s): [@_]\n"; print "scalar: ", scalar(split(/:/, $_[0])), "\n"; print scalar(@_), " item(s): [@_]\n"; print "scalar: ", scalar(split(/:/, $_[0])), "\n"; print scalar(@_), " item(s): [@_]\n"; } sub second { local $" = '], ['; my $x; print "second\n"; $x = shift; print "scalar: ", scalar(split(/:/, $x)), "\n"; print scalar(@_), " item(s): [@_]\n"; $x = shift; print "scalar: ", scalar(split(/:/, $x)), "\n"; print scalar(@_), " item(s): [@_]\n"; $x = shift; print "scalar: ", scalar(split(/:/, $x)), "\n"; print scalar(@_), " item(s): [@_]\n"; } sub third { local $" = '], ['; my $x; print "third\n"; $x = shift; @_ = ($x); print "scalar: ", scalar(split(/:/, $_[0])), "\n"; print scalar(@_), " item(s): [@_]\n"; $x = shift; @_ = ($x); print "scalar: ", scalar(split(/:/, $_[0])), "\n"; print scalar(@_), " item(s): [@_]\n"; $x = shift; @_ = ($x); print "scalar: ", scalar(split(/:/, $_[0])), "\n"; print scalar(@_), " item(s): [@_]\n"; } sub fourth { local $" = '], ['; my $x; print "fourth\n"; print "scalar: ", scalar(split(/:/, $_[0])), "\n"; print scalar(@_), " item(s): [@_]\n"; $x = shift; @_ = ($x); print "scalar: ", scalar(split(/:/, $_[0])), "\n"; print scalar(@_), " item(s): [@_]\n"; $x = shift; @_ = ($x); print "scalar: ", scalar(split(/:/, $_[0])), "\n"; print scalar(@_), " item(s): [@_]\n"; } first('w:x:y:z'); second('w:x:y:z'); third('w:x:y:z'); fourth('w:x:y:z'); __END__ Use of implicit split to @_ is deprecated at ksose.pl line 9. Use of implicit split to @_ is deprecated at ksose.pl line 11. Use of implicit split to @_ is deprecated at ksose.pl line 13. Use of implicit split to @_ is deprecated at ksose.pl line 23. Use of implicit split to @_ is deprecated at ksose.pl line 26. Use of implicit split to @_ is deprecated at ksose.pl line 29. Use of implicit split to @_ is deprecated at ksose.pl line 39. Use of implicit split to @_ is deprecated at ksose.pl line 42. Use of implicit split to @_ is deprecated at ksose.pl line 45. Use of implicit split to @_ is deprecated at ksose.pl line 54. Use of implicit split to @_ is deprecated at ksose.pl line 57. Use of implicit split to @_ is deprecated at ksose.pl line 60. first scalar: 4 4 item(s): [w], [x], [y], [z] scalar: 1 1 item(s): [�] scalar: 1 1 item(s): [x] second scalar: 4 4 item(s): [w], [x], [y], [z] scalar: 1 1 item(s): [w] scalar: 1 1 item(s): [w] third scalar: 2 2 item(s): [8�y], [z] scalar: 1 1 item(s): [�(y] scalar: 1 1 item(s): [��y] fourth scalar: 4 4 item(s): [w], [x], [y], [z] scalar: 1 1 item(s): [0] scalar: 1 1 item(s): [@]
I suspect that the answer to "wtf is happening here" goes deep in the perl code. On the other hand, my question is simple: shouldn't this "deprecation" warning be promoted to become a full-fledged error?
Update: I tried to make the assignment to @_ explicit rather than implicit, and it all seems to go smootly in all tests. In particular, each call to split has been changed as follows:
and the results do not show any surprise:scalar(@_ = split(/:/, $_[0]))
So, it seems that there's no implicit assignment to @_... only clobbering.first scalar: 4 4 item(s): [w], [x], [y], [z] scalar: 1 1 item(s): [w] scalar: 1 1 item(s): [w] second scalar: 4 4 item(s): [w], [x], [y], [z] scalar: 1 1 item(s): [w] scalar: 1 1 item(s): [w] third scalar: 4 4 item(s): [w], [x], [y], [z] scalar: 1 1 item(s): [w] scalar: 1 1 item(s): [w] fourth scalar: 4 4 item(s): [w], [x], [y], [z] scalar: 1 1 item(s): [w] scalar: 1 1 item(s): [w]
perl -ple'$_=reverse' <<<ti.xittelop@oivalf
Io ho capito... ma tu che hai detto?
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: messing with @_
by Fletch (Bishop) on Jun 26, 2008 at 19:49 UTC | |
by polettix (Vicar) on Jun 26, 2008 at 22:58 UTC | |
by Fletch (Bishop) on Jun 27, 2008 at 00:38 UTC |