kasei_sanのブログ

かせいさんのIT系のおぼえがきです。胡乱の方はnoteとtwitterへ

Rubyで書く! Quineのサンプルと解説

Quine ってなに?

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

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

基本の Ruby Quine

eval s="puts'eval s='+s.inspect"

解説

  • eval s="..." では、sに文字列を代入して、それが eval される
  • s の中身は "puts'eval s='+s.inspect"
  • なので、s を eval すると、'eval s='+s.inspect が puts される
  • s.inspect"puts'eval s='+s.inspect".inspect なので、 "\"puts'eval s='+s.inspect\"" となる
  • 結果、puts される文字列は、コードと同じ "eval s=\"puts'eval s='+s.inspect\"" となる

感想

  • s が再起っぽい挙動をするのがややこしいけど、理解すると eval すごいってなる

最短(と思われる) Ruby Quine

puts <<2*2,2
puts <<2*2,2
2

解説

  • 1行目の <<2 はヒアドキュメント
    • なので、2行目はすべて文字列
    • 3行目の 2 でヒアドキュメント終了
  • <<2*2 でヒアドキュメントの内容を2倍にしている
  • puts は複数の引数を渡されると改行してそれぞれを出力する
    • そのため、puts <<2*2,2,2 では改行後に2 を出力する
  • 結果として、コードと同一内容の文字列が出力される

f:id:kasei_san:20190501155916j:plain

感想

パッと見なにしているかわからない感がすごい

もっと短い Ruby Quine

$><<IO.read($0)

解説

  • $> は、 $stdout 標準出力
  • <<オブジェクトを出力させる命令
  • $0 は実行時に指定されたファイル名なので、IO.read($0) で、実行しているファイルの文字列を読み出す
  • 結果として、コードと同一内容の文字列が出力される
  • 仕組み上、irbでは実行エラーになる

感想

これはすこしずるいと思う

更に短い Ruby Quine

0

感想

ずるい

参考リンク

stackoverflow.com