Not particularly new, but reasonably cool, this chunk of code:

#!/usr/bin/perl $s='#!/usr/bin/perl%c$s=%c%s%c;%cprintf($s,10,39,$s,39,10,10);%c'; printf($s,10,39,$s,39,10,10);

prints itself as output. The trick revolves around using printf()'s format tokens to make the string recursive (the %s token), and to nest one set of single quotes inside another (the %c tokens around it). The remaining %c tokens are just newlines (ASCII 10), because \n doesn't work inside single quotes.

If we strip off the unix-specific header, we get:

$s='$s=%c%s%c;%cprintf($s, 39,$s,39,10,10);%c'; printf($s, 39,$s,39,10,10);

which is a little less cluttered, and slightly easier to read.

Here's a variant that uses Perl's q() operator, which nests without requiring token substitution:

$s=q($s=q(%s);%cprintf ($s, $s,10,10);%c); printf($s, $s,10,10);

We can also use the qq() operator (which accepts \n), but this time we have to use token substitution for the dollar signs (ASCII 36). There's no other way to escape them indefinitely:

$s=qq(%cs=qq(%s); printf (%cs, 36,%cs,36,36); ); printf ($s, 36,$s,36,36);

And finally, here's the simplest possible version, using q() again, with literal newlines:

$s=q($s=q(%s); printf ($s,$s); ); printf ($s,$s);

<update>I didn't mean to suggest that this was the smallest possible Perl quine, though I see how the text could be interpreted that way. All I meant to say was that the above code is the simplest version of this particular self-referential Perl statement. Self-reference and its cousin mutual coreference are much more interesting than simple self-replication, IMO. </update>

The trick of using placeholders and substitution is actually one of the deep mysteries of computer programming. The basic idea is simple enough, but the implications (like being able to make infinitely recursive, self-referential strings) are profound.


In reply to Variations on self-replication by mstone

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.