Generating quines in Ruby

Mateusz Lenik – October 1st, 2015

Ruby, Quines

Quines are a very interesting concept in computing as they are self-replicating programs.

Let us start with describing what exactly is a quine – it is a program that prints its own source code, usually to the standard output. It has to store its source code in itself (it cannot rely on the source file laying around on the file system).

For example, this program matches the first requirement, but it does not match the second.

puts File.read(__FILE__)

The simplest quine in Ruby is an empty program, but I would call that cheating since there is no program at all.

Having the requirements, I can start by writing a program that prints out the source of another program.

puts "puts \"hello\""

That was easy! Now, let us adjust it a little bit. This should make the transition to a real quine a little easier.

src = "puts \"hello\""
puts src

This way I can store the whole or just a part of the source in a variable. Now, let us try to replace hello world program source with our program source. It is quite obvious that we will run into infinite recursion as soon as we start putting the assignment in the first line in the source, so let us skip this part for now.

src = "puts src"
puts src

Now we are missing the definition of the src variable, but we cannot put this in a string, since it will introduce the recursion we don not want. The other way to work around it is to generate the src variable definition on the fly from the source string. Luckily inspect can be used to properly escape the string.

src = "puts src"
puts "src = " + src.inspect + src

This is not exactly what we want. The output is still different, but introduction of this intermediate step makes it a lot easier to grasp the transition. Now let us patch the src string to include the rest of the code.

src = "\nputs \"src = \" + src.inspect + src"
puts "src = " + src.inspect + src

Hopefully, you should start to see the pattern here. This pattern is quite general and can be used to write the quine in C (as presented below). The source code uses exactly the same pattern as described above.

#include <stdio.h>

char *s = "\n\nvoid print_escaped(char *s) {\n    putchar('\"');\n    while (*s) {\n        switch (*s) {\n            case '\\n':\n                printf(\"\\\\n\");\n                break;\n            case '\\\\':\n            case '\"':\n                putchar('\\\\');\n            default:\n                putchar(*s);\n        }\n        s++;\n    }\n    putchar('\"');\n    putchar(';');\n}\n\nint main() {\n    printf(\"#include <stdio.h>\\n\\nchar *s = \");\n    print_escaped(s);\n    printf(\"%s\", s);\n    return 0;\n}\n";

void print_escaped(char *s) {
    putchar('"');
    while (*s) {
        switch (*s) {
            case '\n':
                printf("\\n");
                break;
            case '\\':
            case '"':
                putchar('\\');
            default:
                putchar(*s);
        }
        s++;
    }
    putchar('"');
    putchar(';');
}

int main() {
    printf("#include <stdio.h>\n\nchar *s = ");
    print_escaped(s);
    printf("%s", s);
    return 0;
}

First, include a header file that contains definitions of common input output functions. Next, I define a variable to hold the source code string.

After the string I wrote a simple function that will print a properly escaped string. C does not have a function like inspect in Ruby, so I had to implement it on my own. It handles escaping of ", \, and newline characters.

Next, there is a main function which is where the execution of our program starts. At the beginning, as in the previous Ruby quine, it prints the beginning of the program, then it prints the escaped string, and finally the string itself to replicate the original source.

Quine generators

Now, let us take it one step further. The pattern observed above is quite generic, so now I can write a program that generates the quines for us. It really makes the life easier as it deals with all the duplication.

As before, the program has been split into two parts: head and tail. I have edited it very carefully to ensure it generates the original quine in C.

head = "#include <stdio.h>

char *s = "

tail = <<'EOF'.sub('REPLACE_ME', head.inspect)


void print_escaped(char *s) {
    putchar('"');
    while (*s) {
        switch (*s) {
            case '\n':
                printf("\\n");
                break;
            case '\\':
            case '"':
                putchar('\\');
            default:
                putchar(*s);
        }
        s++;
    }
    putchar('"');
    putchar(';');
}

int main() {
    printf(REPLACE_ME);
    print_escaped(s);
    printf("%s", s);
    return 0;
}
EOF

print head + (tail.inspect + ";") + tail

I use REPLACE_ME as a marker to inject the header again in the source. As a bonus, I can use inspect to escape the strings properly.

The general pattern is the same as the one from the previous example, except for it generates C. In order to make it valid C, I needed to append a semicolon to the escaped string.

It is quite easy to write any program as a quine this way. Here is a TCP server quine that prints its source to connected clients in a form of a Gist.

Here is a bunch of tips if you plan to work on it on your own:

  • use diff, it is super helpful: diff -u quine.rb <(ruby quine.rb)
  • git diff can print word diffs, it saves a lot of eyeballing, and can be used like this: ruby quine.rb > out && git diff --word-diff --no-index out quine.rb

If you want to learn more, there is also this thing called “quine relay” that is a program A that generates a program B that generates program A in turn. There is a version available on GitHub that takes it through one houndred languages.

We love to solve tough problems. Got one?   Hire us