Writing quines with Ruby

2022-02-28, 4 min read#ruby#algorithms

Quines are a beautiful programming puzzles. Your goal is to create a program, that will output its own source code, without cheats1 like reading it from the file, or feeding it into STDIN.

A quine is a computer program which takes no input and produces a copy of its own source code as its only output. The standard terms for these programs in the computability theory and computer science literature are "self-replicating programs", "self-reproducing programs", and "self-copying programs".

Quine (computing) - Wikipedia2

I have always considered quines as some sort of Lvl 80 programming magic, up until a point I've decided to write one myself as an exercise.


After looking at a standard example of "constructive" quine in C, it took me around 5 minutes to write a Ruby one, relying on its principles:

s = "s = %c%s%c; print s %c [34, s, 34, 37]"; print s % [34, s, 34, 37]

It's not a most elegant (or short) solution, but it gets the job done. And also it's a good example to explain the principles of constructive quines, so here's my step-by-step process:


  1. Write a program that assigns an empty string to a variable and prints it
s = ""; print s

Note: I'm using a print method instead of puts, because puts would add a newline after printing code. When using puts in a quine, you should add an empty line at the end of a source file.


  1. Mentally divide everything that you're writing in two parts, one is the "opening": s = ", and the second one is the "ending", which at this point consists of "; print s

  1. Add the first part to the string, replacing anything not string-safe with a char format sequence (%c)

In this example double quotes cannot appear inside the string without escaping it with \", so we replace it with %c, and after will use format to substitute that sequence with a character code of double quote mark, which is 34 and can appear in the string without any problems

s = "s = %c"; print s

  1. Now we need to include... the contents of the string itself! The easiest way to do so is by formatting this string, while using the string itself as one of the parameters
s = "s = %c%s"; print s % [34, s]

Running this code will output the following, substituting the %s with a value of a string:

s = "s = %c%s

And this looks exactly like the first part of our program!


  1. Now to the second part: copy your "ending" inside the string, also replacing characters that require escaping
s = "s = %c%s%c; print s %c [34, s]"; print s % [34, s]

Here's both " and % replaced with %c's. This code will fail due to non-sufficient arguments to the format, but that's fine for now


  1. And now add the missing format arguments both in the string and in the code
s = "s = %c%s%c; print s %c [34, s, 34, 37]"; print s % [34, s, 34, 37]

Done! We got a program, that outputs its exact source code, without violating any of the rules.

...but can we do better?

Our current solution is a perfectly functional quine, but a little bit... suboptimal character-wise, so I've played with it a bit.

We can use printf instead of print s % [...], to get rid of escaping the percent sign:

s = "s = %c%s%c; printf s, 34, s, 34"; printf s, 34, s, 34

Then there is a way to get rid of escaping quotation marks, by using .inspect on a string:

s = "s = %s; printf s, s.inspect"; printf s, s.inspect

And then we can shorten it even more, by using %p escape sequence, that will call .inspect for us:

s = "s = %p; printf s, s"; printf s, s

And that is one of the shortest constructive quines in Ruby...

...but can we do weirder?

Have you ever thought how life would be better without having to use explicit variable assignments?

Yeah, me neither.

But there is one of the Ruby's features, that in this case would allow us to assign a variable without assigning a variable!

Here's how it looks:

raise "raise %p rescue printf $!.to_s, $!.to_s" rescue printf $!.to_s, $!.to_s

This abomination not only never explicitly declares a variable, getting rid of =, but also it's the only correct Ruby quine I've seen, that truly fits in a single line, without separating expressions with ;!

Here's a short explanation on how it works:

By raising with a string argument, Ruby internally raises a RuntimeError with this string as a message.

Ruby puts the last exception into a $! system variable, then inline-rescue catches that exception, and feeds it's message into printf twice, formatting it with itself and outputting result into STDOUT.

Please don't show this code to rubocop, I don't want to go to ruboprison for that.

Footnotes

  1. https://en.wikipedia.org/wiki/Quine_(computing)#"Cheating"_quines

  2. https://en.wikipedia.org/wiki/Quine_(computing)


Comments