Perl Signature Quine

Logic chases truth up the tree of grammar.

Willard van Orman Quine, Philosophy of Logic

I use the following signature whenever I post to any of the Perl newsgroups:

    #!/usr/bin/perl -- Russ Allbery, Just Another Perl Hacker
    $^=q;@!>~|{>krw>yn{u<$$<[~||<Juukn{=,<S~|}<Jwx}qn{<Yn{u<Qjltn{ > 0gFzD gD,
     00Fz, 0,,( 0hF 0g)F/=, 0> "L$/GEIFewe{,$/ 0C$~> "@=,m,|,(e 0.), 01,pnn,y{
    rw} >;,$0=q,$,,($_=$^)=~y,$/ C-~><@=\n\r,-~$:-u/ #y,d,s,(\$.),$1,gee,print

If you run this Perl program, you'll find that it prints itself as output (if you're copying it from this HTML page, be careful to undo any HTML escaping that was necessary). A program that outputs itself is called a quine, a term coined by Douglas Hofstadter after the logician Willard van Orman Quine. Note that it's exactly four lines long (the traditional maximum length for a Usenet signature) and exactly 74 columns wide (the margin that I use for Usenet posts).

From time to time, I'm asked how it works. Here's the complete explanation.

The first thing to notice is that it actually begins with a variable assignment, and quite a bit of the rest is a quoted string (starting with q) that uses ; as the quote character. So this is a single assignment:

    $^=q;@!>~|{>krw>yn{u<$$<[~||<Juukn{=,<S~|}<Jwx}qn{<Yn{u<Qjltn{ > 0gFzD gD,
     00Fz, 0,,( 0hF 0g)F/=, 0> "L$/GEIFewe{,$/ 0C$~> "@=,m,|,(e 0.), 01,pnn,y{
    rw} >;

Then we do this:

    $0=q,$,

which just assigns '$' to $0. Now....

    ($_=$^)=~y,$/ C-~><@=\n\r,-~$:-u/ #y,d

makes a copy of the first string that we assigned to $^, puts it in $_ (the default variable for the print we're going to do later), and then does a y/// on it (same as a tr///). I use , as the delimiter for y///. This is the part that decodes the string. The mapping is:

    $/ C-~><@=   ...maps to...
    -~$:-u/ #y

Note that there's a range in there; the range C-~ maps to :-u. You need an ASCII chart to see precisely what that does, but you can apply that transform to the string and get something that looks much more familiar (it includes the string "#!/usr/bin/perl -- Russ Allbery"..., for example.

It also deletes \r and \n characters, to strip off the line endings.

    s,(\$.),$1,gee

is a substitute on the decoded string. $ followed by a single character is replaced by that string evaluated twice (/ee) globally (/g). This causes $0 to turn into $ (so we can escape $'s in the string as $0) and more importantly replaces $^ with the original quoted string. That's the magic that allows the whole thing to be self-printing; the trick to writing self-printing programs is to find a way to use the same string twice in the output.

The quoted string that we put in $^ becomes the text at the beginning and end of the sig after it was decoded, and then the original encoded string is embedded in the middle again to get the original sig back. Note that $/ is also present in the decoded string and becomes \n to preserve the original line endings.

Finally:

    print

just prints out $_, which at this point contains the entire sig.

For more examples of quines, see the quine page.

Last spun 2013-07-01 from thread modified 2013-01-04