Now that I actually read the Wikipedia article, I made the code smaller and 
more elegant ;-)

String streamContents: [ :stream | | lines |
        lines := #(
                'String streamContents: [ :stream | | lines |'
                '       lines := #('
                '       ).'
                '       (lines first: 2) do: [ :each | stream << each; cr ].'
                '       lines do: [ :each | stream tab: 2; print: each; cr ].'
                '       (lines allButFirst: 2) do: [ :each | stream << each; cr 
].'
                '       stream nextPut: $]; cr.'
        ).
        (lines first: 2) do: [ :each | stream << each; cr ].
        lines do: [ :each | stream tab: 2; print: each; cr ].
        (lines allButFirst: 2) do: [ :each | stream << each; cr ].
        stream nextPut: $]; cr.
]

On 17 Jul 2012, at 19:03, Sven Van Caekenberghe wrote:

> 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
> 
> 
> 
> 
> 


Reply via email to