Rubyのなかを覗いてみよう!池澤あやかが「Cookpad Ruby Hack Challenge」に参加してみた
みなさんこんにちは、池澤あやかです。
今回はクックパッド社内で開かれたイベント「Cookpad Ruby Hack Challenge」に潜入してきました。果たして、無事に帰ってこれるのでしょうか!
「Cookpad Ruby Hack Challenge」とは
「Cookpad Ruby Hack Challenge」は、Rubyというプログラミング言語がコンピューターの上でどう動いているのかを知り、ハックしてみるイベントです。8月30日から31日にかけて2日間、クックパッドのオフィスにて開催されました。
このイベントは「Rubyのインタプリタをハックする」という超ディープな内容なのですが、なんと10人の募集枠に約100人もの応募があったのだそう。すごい。今回の参加者は、すこし応募枠を拡大して15人ほどでした。
そんなディープな超人気イベントを、Rubyは好きだけど「インタプリタ」の「イ」の字も知らない私池澤がレポートします!
Rubyに日常的に触れている方は、一度は「Rubyってどうやって動いているんだろう」と思ったことがあるのではないでしょうか。
Rubyで書かれたプログラムは、Rubyのインタプリタ「MRI(Matz Ruby Interpreter)」で解釈され、実行されます。
このインタプリタに機能を追加したり、改良したり、性能を向上させるにはどうすればいいのかを学んでいきます。
今回講師をしてくださるのは、Rubyのコアコミッタである笹田耕一さん。笹田さんは、Rubyがより早く動くためのエンジン「YARV」の開発者で、現在はクックパッド社でフルタイムでRubyを開発しています。
インタプリタを知れば、プログラミング言語の仕組みがわかる!
インタプリタとは一体何をしているのでしょうか。インタプリタというと何やら難しいことをやってそうに聞こえますが、つまり「プログラムを読んで実行する」ということをしています。
具体的には、まずプログラムをパースしてツリー構造(抽象構文木、AST)に、そしてさらにそれをいわゆる「コンピューター語」であるバイトコードに変換します。これが「読んで解釈する」部分。
そしてそのバイトコードを、評価器(evaluator)が読み、実行していきます。これが「プログラムを実行する」部分となっています。
これはRubyに限定したことではなく、JavaやPythonなどの言語も、似たような仕組みで動いています。
▲笹田さんのスライド「Cookpad 17 day Tech internship 2017 言語処理系入門 Rubyをコンパイルしよう」より。ちなみに笹田さんは「YARV」を開発し、バイトコードの解釈をいかに高速化するかという課題に取り組まれています。Rubyが高速化したのも笹田さんのおかげ!
ちなみに、Rubyが誕生してから今年で24年になります。「24年間も開発されていれば、あまり変更されるところもないのでは?」と思う方もいらっしゃるかもしれませんが、プログラミング言語をとりまく環境(例えば、Rubyが動いているOSであったり、コンピューターの性能であったり)というのは目まぐるしく変わっていきます。
そして、ユーザーが求めることも変わっていきます。それに合わせて、現在もなお開発が続けられているというわけです。
Matzが語る、100年先を見据えた言語設計とは
イベントでは、Rubyの生みの親であるまつもとゆきひろさんの特別講義も行われました。
笹田さんからの「いい話をしてください」というオーダーに対し、「Ruby開発と互換性」についてお話されていました。
まつもとさんによると、ブログラミング言語は、常に進化していないといけないけれど、進化しすぎてもいけないというパラドックスを抱えているそうです。
なぜなら、ユーザーは刺激を求めて新しいものを好む傾向にあるけれど、使う人が増えれば増えるほどコミュニティは言語の変化を好まない傾向にあるからです。
例えば、PHP5からPHP6へのアップデートでは、かなり革新的な変更を行ったらしいのですが、革新的であるがゆえにコミュニティに受け入れられず、最終的にはPHP6自体が廃止になったという過去があります。
Rubyは、目先の流行に流されず(今でいうと静的型の導入など)、100年先も通用するような言語を目指して、倦まず弛まず開発が続けられています。
ちょうどRubyコミッターが集まる会議もクックパッドで開催されており、会場にはたくさんのコミッターが集まりました。
イベント参加者がコミッターの方に質問をしまくる「コミッターQ&Aセッション」も行われました。
Rubyの中身をいじってみよう!
それでは、笹田さんが行ってくださった講義の内容を少しご紹介します。
まずは、Rubyのなかを覗いてみましょう!
SubversionやGithubからRubyをダウンロードしてくると、Rubyのなかを見ることができます。
「RubyはCで動いている」と聞いたことがあるかもしれませんが、ディレクトリの中を覗いてみると、確かにそこにはCのプログラムが。
今ダウンロードしてきたRubyを使えるようにするには、このCのプログラムをビルドしてコンパイルしてから、インストールする必要があります。
▲今回のディレクトリ構造。rubyにはRubyのソースコード、buildには、コンパイルしたコード、installには、Rubyをコマンドラインから使えるようにするためのプログラムが入ります。 $ cd rubyhackchallenge$ git clone https://github.com/ruby/ruby.git # GitHubからRubyのソースコードを取得します$ cd ruby$ autoconf$ cd ..$ cd build # ビルドディレクトリに移動$ ../ruby/configure –prefix=$PWD/../install –enable-shared
▲LinuxやMacでのコマンド例です。 私はrbenvでバージョン管理をしているので、インストールディレクトリは.rbenv/ruby/rubyhackchallengeとしました。
さて、まずは簡単なカスタマイズをしてみます。
ruby -vというコマンドを打つと、現在使っているRubyのバージョンが表示されます。この部分のカスタマイズに挑戦してみましょう。
Rubyのディレクトリを見てみると、version.hとversion.cというファイルがあることが分かります。いかにもバージョン定義に使ってそうなファイル名ですね!
さらにversion.cを見てみると、ruby_show_versionというメソッドが定義されています。こちらもいかにもバージョン情報を出力していそうなメソッド名です。
実際に、ここにprintf()を書き加えてみましょう。 /*! Prints the version information of the CRuby interpreter to stdout. */voidruby_show_version(void){
PRINT(description);#ifdef RUBY_LAST_COMMIT_TITLE
fputs(“last_commit=” RUBY_LAST_COMMIT_TITLE, stdout);#endif#ifdef HAVE_MALLOC_CONF
if (malloc_conf) printf(“malloc_conf=%sn”, malloc_conf);#endif
printf(“nyaann”); // 追加
fflush(stdout);}
書き終えたら、コマンドラインからビルドしてコンパイルしてRubyを実行します。 $ make install
▲ 無事表示されました!
次に、ruby 2.5.0devのrubyと表示されている部分を変更してみましょう。これはどうやらruby_show_versionメソッドのなかのPRINT(description);という部分で出力されていそうです。
descriptionを辿ってみると、最終的にはversion.hで定義されているようです。 # define RUBY_DESCRIPTION
“ruby “RUBY_VERSION
RUBY_PATCHLEVEL_STR
” (“RUBY_RELEASE_DATE
RUBY_REVISION_STR”) ”
“[“RUBY_PLATFORM”]”
この「ruby」と書かれている部分を、例えば「python」と書き換えて、先ほどと同じようにビルド&コンパイルして実行してみます。
▲無事表示されました!
このイベントに参加する前までは、Rubyのハックはかなりハードルが高いと思っていたのですが、意外と簡単にハックデビューできるんですね!
ここで豆知識です。プログラムを書き換えるたびに、ビルド&コンパイルしてから実行するので、それなりに時間がかかってしまいます。
そんなときに、Rubyが作られる過程でつくられる、拡張ライブラリを読みこまない機能制限版のRuby「miniruby」を利用することも可能です。こちらを使えば、変更した結果を素早く確認することができます。 $ make miniruby # minirubyとしてビルド&コンパイル$ ./miniruby hoge.rb # minirubyを使ってhogeプログラムを実行する
また、rubyディレクトリに`test.rb`を用意していた場合、以下のコマンドでminirubyで`test.rb`の実行まで行うことができます。 $ make run
オリジナルメソッドを追加してみる
続いては、オリジナルのメソッドを追加してみましょう。Rubyでは、Array#firstというメソッドがあります。array.firstというプログラムを書くと、配列「array」の一番最初の値を返してくれます。
ここにarray.secondというメソッドを加えてみましょう!
配列に関する定義は、array.hとarray.cで行われています。
array.cにsecondメソッドを追加します。 static VALUEary_second(VALUE self){
return rb_ary_entry(self, 1);}
▲array.c。Init_Arrayの上くらいにこのメソッドを書き加えます。 rb_define_method(rb_cArray, “second”, ary_second, 0);
▲array.c。Init_Arrayメソッドの中にこれを書き加えます。
テストも書いておきましょう。test/ruby/test_array.rbがテスト用のファイルになります。
test_firstメソッドの下あたりに以下のコードを加えます。 def test_array_second assert_equal(4, @cls[3, 4, 5].second)end
▲test/ruby/test_array.rb
test.rbにsecondを使ったプログラムを書き、実際に動かします。 [1, 2, 3].second
▲test.rb
make runしてみると、無事secondが使えるようになっていることが分かります。
私自身、「プログラム言語の中身って、なんかよく分からないけど難しそう…」というイメージが強かったのですが、実はこういった部分は単純なメソッドの集合体なんですね。
既存のRubyを少しハックするくらいであれば、意外に簡単にできちゃいそうです。
当日使用した講義資料には、より詳しい解説や追加課題が載っています。ぜひこちらも読んでみてください。
Rubyを魔改造してみる
イベントでは、こうしたちょっとしたRubyのハックを学んだのち、個人個人で課題を見つけて取り組みました。
Rubyのバグを報告するフォーラムに載っているバグを修正する方、デバックに役立つ拡張プラグインをつくる方、など、有意義な課題に取り組む方が多いなか、私は今実行するメソッド名を読み上げるようにRubyを魔改造しました。
minirubyでしか実行できないんじゃい…#cookpad_rhc pic.twitter.com/6j5cO3fWqE
— 池澤あやか / いけあや (@ikeay) 2017年8月31日
Macの標準機能であるSayコマンドを利用したハックだったので、このハック自体はあまり高度なものではありませんでしたが、入力されたコマンドを理解する部分であったり、笹田さんが開発されている「YARV」のコードを一部読んだりすることで、Rubyのしくみの真髄を覗けたような気がして、かなり刺激的でした!面白かったです!
▲まつもとゆきひろさんとコアコミッタの中田伸悦さんにデバックのアドバイスをもらうという……一時なんとも贅沢な展開に……。
求む、新しいコミッタ!
今まで、コミッタになることは死ぬほど高いハードルだと感じていました。
しかし、コミッタになるということは、意外とこうしたハックの延長線上にあるものなのかもしれません。
Rubyのハックに興味を持った方は、今回のイベントの資料はすごく分かりやすくまとまっているので、ぜひ一読してみてください。
今回の記事では紹介しきれなかった拡張機能の作り方や、デバックの仕方などにも触れられています。
また、Rubyのインタプリタについて書かれたサイトや書籍もいくつかあります。
—
* 書籍『Rubyのしくみ』(Rubyのしくみの解説本)
* 書籍『Rubyソースコード完全解説』
(Rubyのしくみを完全網羅した解説本。既に絶版していますが、Webにすべて公開されています。ただし、解説されているRubyのバージョンは、1.8と少し古いものになっています。ちなみに、笹田さんがコミッタになったきっかけは、書籍『Rubyソースコード完全解説』を読んで「これなら貢献できるかも」と感じたことなのだそう)
* サイト『Rubyの拡張ライブラリの作り方』
(Rubyの拡張機能のつくりかたがまとまっています)
—
そして、笹田さん自身も「こうしたイベントは定期的に開催したい」とおっしゃっていたので、クックパッドの開発者ブログやconnpassは今後も要チェックです!
以上、池澤でした。
関連記事リンク(外部サイト)
「お前と働きたいから残ってくれ」フツウの大学生だった僕が長期インターンで掴んだもの
池澤あやか、Facebookの日本オフィスに突撃!――コーディング面接にチャレンジしてきました
社員が「自然と」ユーザー目線に立つ仕掛けは、ランチタイムにあった|クックパッド株式会社
ビジネスパーソンのための、キャリアとビジネスのニュース・コラムサイト。 キャリア構築やスキルアップに役立つコンテンツを配信中!ビジネスパーソンの成長を応援します。
ウェブサイト: http://next.rikunabi.com/journal/
TwitterID: rikunabinext
- ガジェット通信編集部への情報提供はこちら
- 記事内の筆者見解は明示のない限りガジェット通信を代表するものではありません。