In order for a system to reproduce itself, it seems necessary for it to hold an encoded form of itself somehow. This idea, and the inevitability of the existence of DNA-like structures within living cells, is well-illustrated using computer code.
We start with the problem: Write a ruby script that can print itself out, without it reading its own file.
The restriction “without it reading its own file” is important, otherwise a trivial solution would be:
#!/usr/bin/env ruby puts File.read( __FILE__ )
Without thinking about it too much and just starting naively, we may try:
#!/usr/bin/env ruby puts "#!/usr/bin/env ruby\n\nputs \"#!/usr/bin/env ruby\\n\\nputs \\\"#!/usr/bin/env ruby ...
We soon find ourselves entering into an infinite regress that we quickly realize has no escape. Seems we have to be a little bit more clever.
Before getting to the solution, the interested reader is urged to stop reading at this point and try to come up with a solution independently.
Here’s one way to accomplish this. Create the following script, which is just the first step toward the final script:
#!/usr/bin/env ruby require 'cgi' dna = 'DNA' cell = CGI.unescape dna puts cell.sub( 'DNA', dna )
Save the above file as “pregodel.rb”. Next create this helper script:
#!/usr/bin/env ruby require 'cgi' puts CGI.escape( STDIN.read )
Save this as “godelize.rb”, and run it taking pregodel.rb into STDIN:
$ ruby godelize.rb < pregodel.rb
This outputs a cgi-encoded string whose initial characters are '%23%21%2Fusr%2Fbin%2Fenv ...'. Finally, copy pregodel.rb to godel.rb and edit godel.rb. Replace the first instance of DNA with the output of godelize.rb, and save it.
godel.rb should now be:
#!/usr/bin/env ruby require 'cgi' dna = '%23%21%2Fusr%2Fbin%2Fenv+ruby%0A%0Arequire+%27cgi%27%0A%0Adna+%3D+%27DNA%27%0Acell+%3D+CGI.unescape+dna%0Aputs+cell.sub%28+%27DNA%27%2C+dna+%29%0A' cell = CGI.unescape dna puts cell.sub( 'DNA', dna )
When run, the output is identical to the file contents. A conclusive test is comparing md5 sums:
$ cat godel.rb | md5
$ ruby godel.rb | md5
(This was run on a Mac—many linux distros have md5sum instead.)
So what does this have to do with DNA in cells? The godel.rb script is about as simple of a self-replicating ruby script that one can write (again, without invoking the file itself). Its function and structure is surprisingly similar to how a biological cell works. The entire script is stored in the dna variable as a cgi-encoded string, just as a cell is encoded in its nucleus with deoxyribonucleic acid:
dna = '%23%21%2Fusr%2Fbin%2Fenv+ruby%0A%0Arequire+%27cgi%27%0A%0Adna+%3D+%27DNA%27%0Acell+%3D+CGI.unescape+dna%0Aputs+cell.sub%28+%27DNA%27%2C+dna+%29%0A'
The first step in the script's self-replication process is to unescape itself from a cgi-encoded string to ruby code. This is analogous to a cell's ribosomes performing its role in translating DNA into protein. (The intermediate step of RNA transcription is omitted for simplicity without loss of accuracy.) Protein is encoded as sequences of nucleic acids in DNA, just as ruby code is encoded into cgi-encoded character sequences.
cell = CGI.unescape dna
Finally, a cell's DNA must make a copy of itself during mitosis and insert it into the cell's copy. The analog of this is the last line of the script:
puts cell.sub( 'DNA', dna )
Though the dna string has a representation of the whole script, observe how it was able to avoid the infinite regress. The place in the string that references itself, rather than storing itself again (which would lead to an infinitely long string) it instead uses a symbol for itself, namely, DNA. This acts as a placeholder for where the dna variable will be substituted into when the string is printed out.
For further reading, check out the book Gödel, Escher, Bach by Douglas Hofstadter, which applies the above ideas to not only self-replicating cells, but to the nature of mathematical truth, the art of Escher, the music of Bach, and human consciousness, among other related topics.