Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Variations on self-replication

by mstone (Deacon)
on Sep 24, 2004 at 18:19 UTC ( [id://393620]=CUFP: print w/replies, xml ) Need Help??

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.

Replies are listed 'Best First'.
Smallest quine
by sleepingsquirrel (Chaplain) on Sep 24, 2004 at 18:55 UTC
    Inspired by Szymon Rusinkiewicz, here's how to create the smallest perl program which prints its source code to STDOUT.
    $ touch smallest $ perl smallest
    Or, if you system doesn't have the touch command...
    perl -e ''


    -- All code is 100% tested and functional unless otherwise noted.
Re: Variations on self-replication
by ambrus (Abbot) on Sep 24, 2004 at 19:08 UTC

    The shortest one I know is

    print<< x2,v10 print<< x2,v10

    This will be a quine only if you strip the \r's.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://393620]
Approved by Eimi Metamorphoumai
Front-paged by grinder
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (4)
As of 2024-04-25 07:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found