pockestrap

Programmer's memo

階乗を計算するQuine(もどき)書いた

前置き

昨日、DentooLT #7に行ってきました。面白いLTばかりで楽しかったです。

そこで、RubyでQuineを書いたってLTを見ました(Slideshareとかに上がってないのかな…)。

クワイン(英: Quine)は、コンピュータプログラムの一種で、自身のソースコードと完全に同じ文字列を出力するプログラムである。

クワイン (プログラミング) - Wikipedia

ものすごく簡単なQuineをRubyで書くと、こんな感じです。

quine.rb

puts File::open(__FILE__).read
$ ruby quine.rb
puts File::open(__FILE__).read

__FILE__で自身のパスが取得できるので、自分自身が標準出力に表示されています。

ところで、rubyインタプリタスクリプトファイルを与えなければ標準入力をRubyスクリプトとみなして実行されます。

ここで、option は後述のコマンドラインオプション のいずれかを指定します。-- は、オプション列の終りを明示するため に使用できます。programfile は、Ruby スクリプトを記述したファイ ルです。これを省略したり`-' を指定した場合には標準入力を Ruby ス クリプトとみなします。

Rubyの起動

つまり、下のようなことが出来ます。

$ cat quine.rb | ruby
puts File::open(__FILE__).read

ここで、quine.rbは自身を出力するのでした。そのため、次のようなことが可能です。

$ ruby quine.rb | ruby
puts File::open(__FILE__).read

$ ruby quine.rb | ruby | ruby | ruby | ruby | ruby | ruby | ruby | ruby | ruby
puts File::open(__FILE__).read

...ってことをLTで聞いて、その発想はなかったなーと思いました。

本題

ということで、階乗を計算するQuine(もどき)を書きました。

gist11423752

Usage

Ruby をパイプでつないだ数の階乗を計算します。

$ ruby quine.rb
1

$ ruby quine.rb | ruby | ruby
6

$ ruby quine.rb | ruby | ruby | ruby | ruby
120

しくみ

単純に、パイプをつなぐ度にインクリメントしているだけです。

IO#tty?でパイプが途切れたのを判定し結果を計算し出力します。

最後にcatをパイプでつないでやれば、Quineもどきが出力されているのがわかると思います。

環境変数とか使えたら、完全にQuineにできたんだけどなぁ…。
ファイルを使うのは気持ち悪いと思った。