By accident I visited the following website today
http://igoro.com/archive/how-to-write-a-self-printing-program/
It is about writing a self-printing program, also known as a quine
http://en.wikipedia.org/wiki/Quine_(computing)
This has probably been done before, but I had to try to do it in Pharo
Smalltalk.
Paste the following in a Workspace and either print or inspect it.
String streamContents: [ :stream | | lines |
lines := #(
'String streamContents: [ :stream | | lines |'
' lines := #('
' ).'
' stream'
' << ''String streamContents: [ :stream | | lines
|''; cr;'
' tab; << ''lines := #(''; cr.'
' lines do: [ :each | stream tab; tab; print: each; cr ].'
' stream tab; << '').''; cr.'
' (lines allButFirst: 3) do: [ :each | stream tab; <<
each; cr ].'
' stream tab; << '']''; cr.'
).
stream
<< 'String streamContents: [ :stream | | lines |'; cr;
tab; << 'lines := #('; cr.
lines do: [ :each | stream tab; tab; print: each; cr ].
stream tab; << ').'; cr.
(lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].
stream tab; << ']'; cr.
]
The result _is_ the same, but it is a bit hard to see because
String>>#printString renders the printed representation (doubling quotes). To
check you can inspect the string and print it on the transcript (after opening
it)
Transcript show: self
or you can ask the compiler for help
Compiler evaluate: self readStream
if you inspect the result of the above expression, you can keep on doing this
forever.
It is also pretty easy to extend the example with your own code.
String streamContents: [ :stream | | lines |
lines := #(
'String streamContents: [ :stream | | lines |'
' lines := #('
' ).'
' stream'
' << ''String streamContents: [ :stream | | lines
|''; cr;'
' tab; << ''lines := #(''; cr.'
' lines do: [ :each | stream tab; tab; print: each; cr ].'
' stream tab; << '').''; cr.'
' (lines allButFirst: 3) do: [ :each | stream tab; <<
each; cr ].'
' stream tab; << '']''; cr.'
' self inform: ''Cool, no ?'''
).
stream
<< 'String streamContents: [ :stream | | lines |'; cr;
tab; << 'lines := #('; cr.
lines do: [ :each | stream tab; tab; print: each; cr ].
stream tab; << ').'; cr.
(lines allButFirst: 3) do: [ :each | stream tab; << each; cr ].
stream tab; << ']'; cr.
self inform: 'Cool, no ?'
]
Just add the extra code twice.
Enjoy!
Sven
--
Sven Van Caekenberghe
http://stfx.eu
Smalltalk is the Red Pill