This program (spell.pl) prints out the words
"The Perl Journal" in human-readable form.


The program was developed using ActiveState's
Perl 5.005_3 and was tested using Perl 5
builds on Four other Operating Systems (NT,
Solaris, Linux, Digital Unix).


I have chosen to interpret the words "human
readable" to mean that I do not have to print
the ascii characters forming the words. I have 
chosen to make the program print the following
banner (which conforms to the specification,
I believe - if not then submit the archive to
the void faerie!):

____       __                       
 /  / _   /__)_ _ /    /    _   _ / 
(  /)(-  /   (-/ (  (_/()(// /)(/(  


My program uses a number of nice Perl features 
which naturally lend themselves to obfuscation.
The program does NOT rely on lines of code which
do not actually contribute to the goal which is
to print the above banner. Most lines are actually
necessary. I tend to use vaiables like $_, $0, $~
for storage together with $a and $b which are the
only tweo variables not predeclated. $a contrains
the banner (or will contain the banner just prior
to printing to the display). $b is a symbolic 
reference to $a and is used to build the banner
throughout the program (hence the presence of $$b
occasionally). Consider the follwing line:

$b=\q~~,$a='@_=$&,++@_=>$a=~m,.,;@_=$&,',$b="z"=>$a=~y,@_,$a,;$b=~s/./$a/ee; 

This just sets up $b to be a reference to a scalar
(this is a hint!). $a is a string scalar which contains
a line of Perl statements whic only make sense when the
translation is applied (I always use the "y" form of tr
in this program). Sometimes there are lines like $a=$a=
statements to stop warnings for variables used only once!
Basically the statemenst in $a are used in the substitution
at the end of the line (hence the two e's). $b is set to 
"z" and incremented (becomming "aa") and the substitution
makes $b equal "a" at the end. The reason is that when we
dereference $b using $$b then it will point to variable $a
(symbolic reference).

I dont want to explicitly use "print" or "eval" statements
so I use the s///ee form of the substitution operator to execute
lines of code. Also, I dont want to make it obvious that I am
building the commands from stringe in the program so I have
to find them elsewhere. My goal is to produce a line of 
code in the variable $_ which is print"$a\n" and execute it using
s///ee (remember $a contains the banner). So I have two tasks
build the banner and biuld the statement which eventually ends 
up in $_. I get my starting strings from $! which contains the
latest error message. By assigning a number to $! you get an
appropriate error string which can be parsed. $! constantly 
operates in the string context except for assignment so it
is good for obfuscation purposes as it looks like it is operating
in the scalar (numeric) context but it is really (string). I use
$!=4 to generate an error string contraining all of the letters
in "print" in the first word which I insert into $_ prior to 
executing with s///ee. (I have found that $!=4 is the best one
to use following testing of the program with Perl 5 on: W95,
WNT, Red Hat Linux 5.4, SunOS 7, Digital Unix - they all have
different error messages!!)

I also tend to use other forms for s///ee line s,,,ee etc. just
to reading dificult, especially when I use "," instead of ";". I
like to build strings and then make them look like variable 
interpolation is taking place. The letters in the string are
extracted using positional information. The original string is 
"Interrupted" which becomes "ruptederint" following line and
resides in $_.

;$~=$!,$~=~s/^(\w*).*/$1/,$~=~s/^(...)(..)(.*)/$3$2\l$1/;$_=$~,,$~='';s,(.),

I also use the fact that $| always has the value 0 or 1 (and is 1
irrespective of assigned values whci are greater that 1).

I use a subroutine to build the string print from "ruptederint"
using letters 3,8,9,10 and 11. I incrementally (read globally) match
letter number using the regular expression "(3|8|9|10|11)" and hence
build the string "print" using the match operator in the following line

@_[0=>1]=(++$_[0]=>$&)=>$~.=($_[0]=~m.^$0$.)?$_[1]:'',ge,,=>,,s,^.*$,qq*$~*.

(hence the g and e). The order of the regular expression doesn't matter
but the order in which the string is formed does, hence the re-ordering
of the word "Interrupted" previously. I use the ternary operator "?:" 
instead of "if" statement. The following line does the print and just
have a useless end of program marker to make the lines neater :)

q*^$*.q*a\\*.q.n^.,e,$0=$_,$$b=$a,$0=~s,,$_=~y~^~"~;$_,ee;s!This is!the end!

The rest of the program is concerned with makking the banner and the 
string containing "(3|8|9|10|11)". This string is generated using a call
to an anonmymous subroutine which when called makes this string in the 
global variable $_ (this gets used for lots of things depending on the
time!!). A call to the anonymous subroutine is built in $~ and looks like
"${$__->(1)->(1+1)->(1+1+1)->(4)->(1)}" then called using a s///ee again.
$__ is a reference to the anonmymous subroutine which returns a reference.
The reference returned is either a reference to itself or to a variable
containing the string "(3|8|9|10|11)" (which the subroutine builds as a
side effect!) after the last (ie. fifth call) to the subroutine. The number
of calls to the subroutine is held in a global variable ($0) for the duration
of the call. The subroutine call string is built using the following lines 
(remember that $| is only ever 0 or 1 and never higher that 1 no matter what
you think it is!)

y,*^&%,=_[],,$|++;s,,$0=$|+$|+$|+$|;$0++;$_,ee,s,(.*),(),=>($~=qq.\${\$__(..
(++$|).qq.)($|+$|)($|+$|+ $|)(..(($|+$|)+($|+$|)).qq.)($|)}.)=~s/\(/\->\(/g,;

Finally, the anonmyous subroutine is automatically generated in a string
variable ($_ again) which is executed inside a s///ee statement. A by-product
of executing this string is the genreation of a global reference $__ which
points to the anonmyous subroutine. The routine multiplies a global variable
by two, increments it, and adds whatever was passed as a parameter to the 
resultinc sum. This sum is then append (string context) to another global
variable with a "|" for good measure and returns a reference (see earlier
note on return reference). The subroutine defined in looks like this

$^^*sub{s,(\(),$1.($0+$0+$_&0%).(($0!*5)?'|':''),e;$0--**1?\$^:$^^}

after lines

$_=$~,s~(.).*(.).~\L$1$2a~,$_++,s,^,\$^^*,,s,$,{},=>s,{,{\$0**1?\\\$^:\$^^,,
s,(\d),$1--,=>s~{~{s,(\\(),\$1.(\$0+\$0+\$_&0%).((\$0!*5)\?'|':''),e;~,$!++,

so it has to be translated to 

$__=sub{s,(\(),$1.($0+$0+$_[0]).(($0!=5)?'|':''),e;$0--==1?\$_:$__}

using the "y" operator at the beginning of line

y,*^&%,=_[],,$|++;s,,$0=$|+$|+$|+$|;$0++;$_,ee,s,(.*),(),=>($~=qq.\${\$__(..

Note that even in the subroutine the lines of code are executed inside the
s///e operator (I just love this!).

The rest of the program just builds the banner: It looks like this
before it is changes with the "y" operator:

@@@@~~~~~~~@@~~~~~~~~~~~~~~~~~~~~~~
~$~~$~@~~~$@@+@~@~$~~~~$~~~~@~~~@~$
_~~$+_-~~$~~~_-$~_~~_@$_+_$$~$+_$_~

These lines are interspersed with the rest of the code described above. I also
use "," and "=>" (syntactic sugar) to replace ";" where possible especially 
after I use s,,, instead of s/// etc. Sometimes I use the "q" and "qq" operators
for strings to help with padding to make the program lines have a similar length.


C'est tout!

John Keating (31 July 1999
