技術部の遠藤です。CookpadのフルタイムRubyコミッタの1人です。RubyKaigiまであと1週間ですね!
今年のRubyKaigiでは、"TRICK"の発表をします。TRICKとは何か。まずはこのRubyコードを見てください。
->\ &\ w{ a= ?a b= ?b c= ?, d= ?. e= ?e g= ?g h= ?/ i= ?{ l= ?l m= ?_ n= ?$ o= ?1 q= ?' r= ?< s= ?s t= ?> u= ?u v= ?v x= ?( y= ?) z= ?- _= "" f= w[ w, z+ t+ i+ m+ r+ r+ m+ o+ d+ g+ s+ u+ b+ x+ n+ h+ c+ q+ q+ y+ ?} ]; f[ 'p ut s" He ll o, '] _\ << 32 f[ 'w or ld !" '] w[ w, e+ v+ a+ l+ x+ m+ y] }[ &[ *( :\ a\ .. :\ ÀÀ )% (0 3\ ** 7* 47 ;) ][ +1 ]]
もう一度いいますが、これは「Rubyコード」です。保存して実行すると、"Hello, world!"と出ます。
$ ruby hello.rb Hello, world!
TRICKとは、こういう変なRubyコードで競い合うプログラミングコンテストです *1 。読めないけれど面白い投稿作品(プログラム)が選定され、表彰されます。
TRICKは2013年、2015年、2018年とやってきて、今回は4年ぶり4回目の開催になりますが、いままでで一番レベルの高い戦いになったと思います。というのも、上のプログラムは、TRICK 2022に落選したプログラムです。*2
つまり、当日はこれよりすごい入賞作品たちが紹介されます。TRICK 2022 Resultsは1日目の夕方です。ご期待ください!
おまけ
開発者ブログなので、上記のプログラムの技術解説を軽く書いておきます。
基本構造はこうなってます。
-> &b { b["dummy", "<main code>"] }[&:eval]
ラムダ式に:eval
をブロックとして渡すことで、:eval
が暗黙的にto_proc
でProcに変換されます。そのProcに"<main code>"
が渡されることで、Kernel#eval
が呼び出されて、最終的にmain codeが実行されます。
<main code>
のところは、↓のような感じで縦長にしています。
a = ?p b = ?u c = ?t d = ?s a + b + c + d #=> "puts"
一番むずかしかったのが:eval
というシンボルを作り出すところです。あっさりネタをばらすと、:a
から始まるシンボルのRangeを列挙すると、102,789番目が:eval
です。
(:a..:ÀÀ).to_a[102789] #=> :eval
:ÀÀ
というUnicodeなシンボルを使うところが肝。2文字分でありながら4バイト超なので、列挙が途中で打ち切られずに:a
から:zzzz
までの配列が得られます。
あとは読み解いてみてください。
なお、実際に投稿したのはHello, world!ではなく、任意のRubyコードを縦長に変換するコードでした。完全な投稿は↓に置いたので興味あればどうぞ。
おまけのおまけ
ぜんぜん別の宣伝ですが、RubyKaigi当日はぜひ会場内のクックパッドブースに来てみてください! 今年もなんか企画が用意されているはず。