はじめに
Rubyのクワインとして紹介されていた2つを解読してみました。
割と頭がこんがらがるので、順を追って書いていきます。
コードは下記から拝借しました。
https://stackoverflow.com/questions/2474861/shortest-ruby-quine/2475931#2475931
1つ目
コード
_="_=%p;puts _%%_";puts _%_
解説
まず、演算子の前後にスペースを入れます。
セミコロンは改行します。
_ = "_=%p;puts _%%_"
puts _ % _
1行目は変数_
への代入式でした。
2行目で参照しているので、展開します。
puts "_=%p;puts _%%_" % "_=%p;puts _%%_"
%
演算子の挙動はsprintfと同様です。フォーマット、変数の順です。
%p
はObject#inspectの結果で置き換えられます。
%%
は%自身を出力します。
%p
の前後で分割して、敢えて文字列連結で書くとこうなります。
puts "_=" + "_=%p;puts _%%_".inspect + ";puts _%_"
inspect
の結果を展開して
puts "_=" + "\"_=%p;puts _%%_\"" + ";puts _%_"
文字列連結します。
puts "_=\"_=%p;puts _%%_\";puts _%_"
あとはputs
の出力結果を見るだけです。
_="_=%p;puts _%%_";puts _%_
2つ目
コード
puts <<2*2,2
puts <<2*2,2
2
解説
このコードはヒアドキュメントを使っています。
1行目の<<2
が開始ラベル、2行目が本体、3行目が終端行です。
また、Rubyでは開始ラベルが値を返すので、続けて*2,2
と処理を書いています。
まず、演算子の前後等に空白をいれます。
puts <<2 * 2, 2
puts <<2*2,2
2
ヒアドキュメントを展開してみます。
改行があるので注意をしつつ
puts "puts <<2*2,2\n" * 2, 2
*
演算子は文字列を指定した回数分繰り返します。
puts "puts <<2*2,2\nputs <<2*2,2\n", 2
あとはputs
の実行結果を見るだけです。
与えられた引数を続けて出力します。
puts <<2*2,2
puts <<2*2,2
2
参考
- Shortest ruby quine. (n.d.). Stack Overflow. Retrieved June 19, 2021, from https://stackoverflow.com/questions/2474861/shortest-ruby-quine/2475931#2475931
- class String (Ruby 3.0.0 リファレンスマニュアル). (n.d.). docs.ruby-lang.org. Retrieved March 24, 2021, from https://docs.ruby-lang.org/ja/latest/class/String.html