There are actually two things happening here that cause this code to require 5.6.
The prototype for unpack wants the first argument (the format) to be a scalar value. The first argument is actually evaluated in a scalar context.
@args = ('a5', 'qwert');
unpack @args; # not okay; equivalent to unpack 2
+;
unpack $args[0], @args[1..$#args]; # okay, format arg followed by dat
+a args
The reason why Anonymous Monk's code works in 5.6 but not in 5.005 is due to a change in the implementation of qw//.
As you know, qw/STRING/ is equivalent to split ' ', 'STRING'. In 5.005, the split is performed at runtime, but in 5.6, the split occurs at compile time!
Thus, given this code:
unpack qw/a5 qwert/;
perl5.005 compiles it as:
unpack split ' ', 'a5 qwert';
which puts split in a scalar context, and leaves unpack with only one argument.
perl5.6, on the other hand, compiles it as:
unpack 'a5', 'qwert';
and unpack is happy.
In conclusion, here's a version of Anonymous Monk's JAPH which runs in earlier versions of perl:
($#=unpack u, q&>>7,@2D%U='ET96YR;VAY96P@(%!R>6-E2')A:RP*&)
=~s:y(.)(.)(.)(.)(.)(.):\3\5\1\6\2\4:g; print 42;
| [reply] [d/l] [select] |