entry-header-eye-catch.html
entry-title-container.html

entry-header-author-info.html
Article by

Rubyコア最前線 pixiv inside出張版

皆さんこんにちは。最近はGoでコードを書いてることが多いですが、実はRubyコミッターという肩書も持っているusaです。

Rubyといえば、毎年クリスマスの頃に新バージョンがリリースされる事が多いですね。 もちろん今年も、Ruby 2.6のリリースが予定されています。 新しいRubyではどんな変更が入るのか、ということに興味がある方も多いかとは思いますが、そういった記事は探せばたくさん見つかると思います。

本稿ではそういう話ではなくて、Rubyにどんな変更が入るのかがどうやって決められているのか、ということを紹介します。

Ruby開発者会議

普段から皆さんの目に触れるWebサービスなどで広く使われているRuby。もちろん、ピクシブ社内でも様々なサービスがRubyで作成され、ユーザーの皆さんに向けて提供されています。

コミッター

さて、当然のことながら、Ruby自身もプログラムですから、誰かがRuby自体を開発していることになります。 Rubyの作者であるmatzことまつもとゆきひろ氏は広く知られていると思いますが、現在のRubyの開発は「コミッター」と呼ばれるRubyソースコードに対する変更権限を持つ開発者たちによって行われています。

Rubyのコミッターとして登録されている開発者は現在100人前後です。 もちろん、matzもコミッターの一人です。

Rubyの各コミッターには、基本的にはそれぞれの担当領域があります。 各コミッターはその担当領域内においてはだいたい自由にRubyのソースコードを変更してよいことになっています。

議題

とはいえ、各々のコミッターがバラバラに好き勝手にRubyを変更していては方向性も定まりませんし、毎年クリスマス頃に予定されている新バージョンのリリースに際してどんな新機能を入れるのかといった計画も立てられません。

そこで、コミッターのうちの有志、具体的には主に東京近郊に在住するコミッターが、月1回くらいのペースで集まって「Ruby開発者会議」を開催するようになりました。

Ruby開発者会議では、Rubyのイシュートラッカーに寄せられている機能変更リクエストを中心に、コミッターたちが対面で議論して、何をやるのかやらないのか、やるならいつまでにやるのか、ということを決定しています。

なお、Rubyの機能追加・変更についてはmatzが最終決定権を持っているので、必ずmatzにも参加してもらっています。

会場

Ruby開発者会議には、毎回、およそ10人強のコミッターが参加します。 加えて、リモート接続で参加するコミッターも毎回数人ずついます。

この人数を収容できて、数時間占有出来て、かつ、ネットワーク接続がある場所、となるとなかなか条件が難しいため、毎回、コミッターの誰かが所属する各社に会場を提供してもらっています。

幸い、ピクシブにはこの条件に合うミーティングルームがあるので、たびたびRuby開発者会議の会場となっています。 特に、ここ数ヶ月は連続でピクシブでの開催となりました。

というわけで、皆さんにRuby開発者会議というものはどのような感じで行われているのか、という一端を紹介します。

和気藹々

会議の内容

まず、実際の開催の前に、RubyのイシュートラッカーにRuby開発者会議のお知らせが登録されます(2018年12月の例)。

Ruby開発者会議に参加できるのは、原則として、コミッターおよびコミッターに招待された人だけなのですが、参加資格のない一般のユーザーや、参加資格がありそうでも当日参加できない人は、このイシューに議論してほしい話題を登録しておけば、可能な限り会議の場で取り上げられることになっています。

実際にRuby開発者会議が始まると、まず、次回の開催日を相談して決めます。 基本的にはmatzの都合のいい日の候補をいくつか聞いて、その中から他の参加者や会場の都合がいい日を選んでいます。 その後は、実際の議題の検討に入っていきます。

Rubyはユーザーフレンドリーを目指しているので、非参加者がイシューに登録してくれた議題を先に議論します。 その後、参加者が持ってきた議題について議論し、だいたい4時間前後で終了となります。

では、具体的にどのような議題があって、どう議論されて、どんな結論を出しているのか、議事録を眺めながら幾つか実例を挙げてみましょう。

例1. [Feature #13581] Syntax sugar for method reference

Rubyでは Module#method メソッドを使うとメソッドをオブジェクト化できるわけですが、それを簡単に書ける文法を導入しよう、という提案です。

割と古くから繰り返し現れる提案ですが、なかなかいい記法が決まらないのでずっと先送りになってきました。 しかし最近の開発者会議で繰り返し議論を重ねてきた結果、.: ならまあいいか、という雰囲気が醸成されてきています。

今回は、 (...) と後ろに書いたらメソッドオブジェクトになるというのはどうか(Luaがそう)、という提案と、仮に .: になったとしたら &.:meth みたいに書けるべきかどうか(&self.:methselfを省略可能とするか)、という議題が検討されました。

結果として、前者は文法衝突もあるし別の意味に将来使う可能性があるので却下、後者も &:meth と外見上似すぎているのに意味が違うので却下、となりました。

例2. [Bug #15303] Return tracepoint doesn't fire when tailcall optimization is applied

Rubyのあまり知られてない機能の一つに、コンパイル時末尾呼び出し最適化というものがあります。

要するに、メソッドの末尾が他のメソッドの呼び出しである場合、新しくコールフレームを積んでそのメソッドを呼び出すのではなくそのメソッドの先頭へのジャンプで済ましてしまう、というものです。 実際のところ、Rubyの場合、それが再帰呼び出しとかでもない限りあまり恩恵がないため、この機能はデフォルトではオフになっていて、特別な方法を使わない限り有効にはなりません。

さて、一方で、Ruby用のデバッガなどを作る際に使うための、TracePointという機能があります。 TracePointを使うと、メソッド呼び出しやreturnなどのイベントをフックすることができるのですが、末尾呼び出し最適化を有効にすると、メソッド呼び出しがジャンプに変化してしまうため、そこのイベントが発火しなくなるという問題が報告されました。 末尾呼び出し最適化は意図的に有効にしない限りオフのはずなので、わかってるユーザーがやる分にはイベントが発火しなくてもしかたない……というはずだったのですが、実はRubyの標準添付ライブラリであるforwardable.rbでこれが有効にされているために問題が発生していました。

解決策として幾つかの案が提案されたのですが、議論の結果、リリース直前である2.6に間に合わせることを考えると、TracePointの挙動を変更するよりは、単にforwardable.rbから末尾呼び出し最適化を有効にしている処理を取り除いた方がよかろう、という結論となりました。

Ruby開発者会議では、このような感じで、さまざまな議題について議論して一つ一つ結論を出していきます(もちろん、結論が出ずに先送りになることもよくありますが)。

ピクシブのエンジニア勉強会

さて、Ruby開発者会議自体は以上の通りの内容ですが、ピクシブでは、毎週金曜日に、社員有志が面白そうな技術的な話題を持ち寄って発表する、エンジニア勉強会というものが行われています。

そこで、筆者は、毎月のRuby開発者会議の開催後のエンジニア勉強会で、開発者会議の内容のうち有益あるいは面白そうな部分を抜き出して「Rubyコア最前線」と称して発表しています。 内容としては「前回決まった内容のその後」「今回採用が決まった機能追加・変更」「今回リジェクトされたネタ」となっています。

上述した例1がリジェクトされたネタ、例2が機能追加・変更に相当しますが、発表の際には決定に至った背景や全体の温度感なども伝えて、Ruby開発の意思決定の雰囲気が伝わるように心がけているつもりです。

もちろん、ピクシブのエンジニア勉強会では毎週他にも面白くて参考になる発表が盛りだくさんです。 Rubyに興味がある方でも、他の技術に興味がある方でも、聞いてみたい方はぜひこの辺りからご応募を!

20191219022311
usa
ImageFluxチーム所属。普段のお仕事は画像処理等のコードをいじること。 2000年よりRubyの開発に携わり、現在は主にWindows版の開発および安定版の保守を担当。Ruby公式サイトに世界で一番多く記事を書いている人。