quine は極めてる人がいっぱいいるので quine の変種を考えてみました。あんまりいいのを思いつきませんでしたが、誰かがもっと面白いのを考える種になるといいなと思いつつ晒します。
Python -> Ruby -> Perl -> Python .. と回るプログラム。quine っぽいのは python だけなので全然ダメ。
q='print "puts %%(print q(q=%s;exec q).$/)"%`q`';exec q
$ cat quine.rb.pl.py |python |ruby |perl > q $ diff quine.rb.pl.py q
Hello, world! 。標準エラー出力に 1 文字だけ出力したら、残りを出力するプログラムを出力して終了します。
"Hello, world!\n".instance_eval q=%q(STDERR.putc c=self[0];puts (self[1..-1]+c. chr).dump+%(.instance_eval q=%q(#{q})))
$ ruby quinehello.rb H"ello, world!\nH".instance_eval q=%q(STDERR.putc c=self[0];puts (self[1..-1]+c. chr).dump+%(.instance_eval q=%q(#{q}))) $ cp quinehello.rb q.rb; while ruby q.rb > q2.rb; do mv q2.rb q.rb; done Hello, world! Hello, world! Hello, world! ...
上とほとんど同じですが、brainfuck インタプリタ。1 命令だけ実行して、残りを実行するプログラムを出力して終了します。1 行目の配列が、現在の実行位置、現在のポインタ位置、現在のテープ状態を表します。こんな風にプログラムを書いておけばプロセスマイグレーションがとても簡単ですね (笑)
[0,0]. instance_eval a=%q(c,f,*t=self;t[f]||=0;eval({?>=>'f+=1',?<=>'f-=1',?+=>'t[f]+= 1',?-=>'t[f]-=1',?[=>'t[f]==0&&(d=0;(c+=1;d+={?[=>1,?]=>-1}[n[c]]||0)while d>=0 )',?]=>"d=0;(c-=1;d+={?[=>-1,?]=>1}[n[c]]||0)while d>=0;c-=1",nil=>"exit 1;;;", ?,=>'t[f]=STDIN.getc',?.=>'STDERR.putc t[f]',}[(n=DATA.read)[c]]||"");$><<("%p. "%[[c+1,f]+t])+"instance_eval a=%q(#{a})\n__END__\n"+n) __END__
$ cat hello.bf
+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.
------------.<++++++++.--------.+++.------.--------.>+.
$ time (cat quinefuck.rb hello.bf |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |ruby |
ruby |ruby |ruby; echo)
Hello, world!
real 0m9.715s
user 0m3.370s
sys 0m6.250s