http://qs321.pair.com?node_id=282636


in reply to Just convoluted

Excellent, ++ (as soon as i get votes again)
I don't think i've seen a lot of scripts which abuse the perl internals this much..

Spoiler below

This was fun. For readabilities sake, download the code..
Quick download code link

#!/usr/bin/perl @_=(shift,pop); # we take the first and the last element of ARGV which + contains the # 4 argumants of 'Just another perl hacker' @ARGV is n +ow ('another','perl') $*={ ord"<" => # we create the hash $* with 1 key-value pair. the k +ey is ord("<"); # the value is a reference to an anonymous array whi +ch contains # a reference to an anonymous sub. # ord"<" is 60, which happens to be the default valu +e for $= # $& the string matched by the last successful patte +rn match # $. is the line number in the file we are reading. +As we are reading no # file this is 0. # $|,the output autoflush is 0 by default and is inc +remented on the last line [ sub{ printf "%s",shift; # print the first argument passed join $&,@ARGV[$.,$|] # join remaining elements in @ARGV + by $& which will be ' ' because of # the regex to be executed soon. A +s $. is 0 and $| is 1 because of # the foreach on the last line we +are joining 'another' and 'perl' # together. } ] }; $\=( # $\ is the output record separator for print ($,)=$"=~?( )? # by default $" contains a space # it gets matched by ~/( )/ and put # in $, which is by default a empty scalar # also the result of this succesfull match is +put in $& ) && # if the match was succesfull qq; $_[$#_]\n;; # Perl evaluates this line which # due to the assign to @_, $_[$#_] results in +' Hacker\n' # # If the regex wouldnt match the second part w +ould not have # been exectuted. # Now if you print a list, it is terminated by ' Hacke +r\n'; # Read the following section backward. Starting with 1, then moving up + to 3. # # print+chop$, # 3. The result of the function called in 2. i +s in $_ and $, (a space) is chopped off, # the result of the chop function is printe +d. # # However, as the OUTPUT_RECORD_TERMINATOR +is set to ' Hacker\n' # the printed string is appended by this. ( +Note that the print in called # sub was actually printf ,$*->{$=}->[$[]->($_) # 2. $[ is first array index. By default 0 and + hasn't been reset # so actually we are saying: # $*->{60}->[0]->($_) (so we call $*->{60}- +>[0]->('Just'); # the return value from the called function + is 'another perl' foreach($_[$|++]); # 1. We return 'Just', as soon as element $_[0 +] is returned $| is incremented by 1.

Update: removed a mistake about $| not being modified in the program.

Replies are listed 'Best First'.
Re: Re: Just convoluted
by b-funk (Sexton) on Aug 21, 2003 at 02:58 UTC
    No internet at the new house, so I haven't had a chance to reply. Thanks for the compliments, and nice work on deciphering the code. I would say something about being a newbie, but that kind of detracts from the previous compliment ;-)