207 Quine

Description

Ahn nyeong Rubyists,

This week’s quiz is to create a quine, that is: a program which receives no input and produces a copy of its own source code as its only output.

Have Fun!

Summary

There were a great many solutions to the quiz this week. Let’s dive in!

Robert Dober, along with others, had the shortest quine at zero bytes. Robert also had the longest quine. His quine has methods, including a module, clean formatting, and is even self checking! It checks its output by reading the file in $0 to make sure it matches.

Matthew Williams had an interesting take: use Ruby2Ruby to handle translating a class into text.

require 'rubygems'
require 'ruby2ruby'

class Quine < Object
  def initialize
    puts "require 'rubygems'\nrequire 'ruby2ruby'\n\n#{Ruby2Ruby.translate self.class}\nQuine.new\n"
  end
end
Quine.new

There were also several classic solutions. Pascal Bourguignon was the first to submit one and it is a great example:

q=34;printf a="q=34;printf a=%c%s%c,q,a,q;puts",q,a,q;puts

The q=34 is a double quote character. The string containing the program is stored in a. Then that string is given to printf and expanded and quoted here: a=%c%s%c. The shortest classic solution was 28 bytes, submitted by Matthew Williams:

a="a=%p;puts a%%a";puts a%a

All of the classic solutions pass the piping test, suggested by Brian Candler:

cat quine.rb | ruby

This eliminates tricks with __FILE__ and $0. Speaking of tricks with __FILE__ and $0 there were also many solutions that used those tricks effectively. Jorrel submitted a good example of this kind of quine:

puts File.readlines __FILE__

It’s not the shortest but it illustrates the principles nicely.

James Gray demonstrated an interesting use of DATA:

DATA.rewind
puts DATA.read
__END__

A solution using $0 comes from Sebastian Hungerecker:

system"cat",$0

The advantage here is that it doesn’t matter if the filename has spaces or not, but like all of the quines in this category it fails the piping test because the file is not available for the piped input stream to read.

And finally, there are the extremely short quines. These usually make some assumptions about being run on *NIX possibly with some special setup before hand.

Martin DeMello gets one in at 10 bytes, if you alias cat to c, 12 bytes if you don’t. His solution also requires calling ruby with the -p option. It also does not pipe successfully but still quite inventive.

> echo | ruby -p quine.rb
$_=`c #$0`

Joshua Ballanco, in a beautiful abuse of the rules, gets down to 8 bytes, and it successfully pipes. There is some setup involved, and it assumes *NIX, so it is unlikely to work ‘out of the box’ on most machines.

> cat a
$><<`a`

> ruby a
$><<`a`

> cat a | ruby | ruby
$><<`a`

> which a
/usr/local/bin/a

> cat `which a`
#!/usr/bin/env ruby
puts '$><<`a`'

The environment in which a program reproduces is not easily separable from the program. When you include all of the implicit assumptions the requisites for self perpetuation quickly add up. You need version of Ruby, an operating system with certain features, a file that the code exists in… In order for a program to truly reproduce it may need to include a runtime environment, an operating system, maybe even the hardware to run on. In any case there is not always a dividing line that can be drawn between an reproducing entity and its environment without severing reproducibility and that line is usually arbitrary.

I hope you all enjoyed exploring quines this week.

Quine (#207) - Solutions


Friday, May 29, 2009