Just another perl hacker

From Citizendium
Revision as of 01:45, 31 May 2007 by imported>Aleksander Stos (Perl example 3 moved to Just another perl hacker: This has more 'universal' meaning, independent of our content)
Jump to navigation Jump to search

Example: $ perl -e 'print grep(s/^\d+(.*)/$1 /, sort(split(/ /,"8hacker, 4Perl 1Just 2another")));'

Result:
Just another Perl hacker,

Perl is evaluated from inside to outside of parens and from right to left, so ist is possible to squeeze all steps into a one-liner like the one above. But the example will be much more understandable if it is expanded into a program using intermediate variables:

$string = "8hacker, 4Perl 1Just 2another";
 
## split $string on white space (/ / is a shortcut with special meaning in context of `split')
@list   = split(/ /,$string);    # resulting in $list[0] = '8hacker,', list[1] = '4Perl', etc.

## the leading numbers are for the benefit of the builtin sort directive
@sorted = sort (@list);          # resulting in $sorted[0] = '1Just', $sorted[0] = '2another', etc.

## the following pattern detects a leading (shortcut '^') digit (shortcut \d, the '+' means at least one)
## and caches ('capture' shortcut '()') the remainder ('all characters' shortcut '.*')
$pattern = '^\d+(.*)';

## the example uses the builtin 'grep' and we could be done right here:
@result1 = grep(s/^\d+(.*)/$1 /, @sorted);

## but for a step-by-step explanation we will convert the grep into an equivalent loop:
@result2 = ();                   ## initialize to empty list, actually the default
@index   = (0 .. $#sorted);      ## ($#sorted: shortcut for index of last element of '@sorted')

foreach $index (@index)          ## ($index and @index are two independent variables!)
{
  ## to 'use =~ s///' directly on $sorted[$index] 
  ## would change the element, so we use a temp variable

  $tmp = $sorted[$index];
  $tmp =~ s/$pattern/$1/;        ## e.g. substitute '4Perl' with 'Perl'
  $result2[$index] = $tmp;
}

## a 'print @list' automatically inserts the output field separator ('$,')
print "result1:",@result1,"\n";
print "result2:",@result2,"\n";

Voila:
result1:Just another Perl hacker,
result2:Just another Perl hacker,


But what do you think is the output of this 2003 beauty from perlmonks.org?

$ perl -e '
not exp log srand xor s qq qx xor
s x x length uc ord and print chr
ord for qw q join use sub tied qx
xor eval xor print qq q q xor int
eval lc q m cos and print chr ord
for qw y abs ne open tied hex exp
ref y m xor scalar srand print qq
q q xor int eval lc qq y sqrt cos
and print chr ord for qw x printf
each return local x y or print qq
s s and eval q s undef or oct xor
time xor ref print chr int ord lc
foreach qw y hex alarm chdir kill
exec return y s gt sin sort split
'

Yep. "just another perl hacker". Just don't ask why ...