技術部の遠藤です。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当日はぜひ会場内のクックパッドブースに来てみてください! 今年もなんか企画が用意されているはず。