http://www.perlmonks.org?node_id=694245

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:

#!/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[�]
What's that junk?
My first thougth was to turn warnings on to see what was happening, and something popped out indeed:
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.
(k`sOSe is the nickname of the guy, BTW.)

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.

#!/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): [@]
Only the second sub seems to be working properly.

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:

scalar(@_ = split(/:/, $_[0]))
and the results do not show any surprise:
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]
So, it seems that there's no implicit assignment to @_... only clobbering.

perl -ple'$_=reverse' <<<ti.xittelop@oivalf

Io ho capito... ma tu che hai detto?