WEBCAMP ENGINEER COMMUNITY のカレンダーの14日目はQiitaの @kyntk が担当します。
「Rubyのしくみ」を読んだので、その感想をまとめました。
日本語版序文として、まつもとゆきひろさんの以下のようなコメントがあります。
Rubyを便利につかっていても、その中がどうなっていて、どのように実行されているのか、あるいはRubyのような言語をどうすれば再現できるのか正確な知識を持っている人はほとんどいないでしょう。本書はそのような謎につつまれている「Rubyの中身」を明らかにしてくれる一冊です。
この本は、Rubyがソースコードをどのように解析をしてどのように実行するのかという、Rubyの内部について書かれている本です。主にはMRI(CRuby)をベースに進められますが、C言語の知識がなくても理解ができるように、丁寧に図で説明されています。
私がこの本を読もうと思った理由は、
- JITが導入されたけど、今までと何が違うのか、今後どうなっていくのかを知りたいと思ったから
- Rubyをもっと使いこなすために、Rubyについて知りたいと思ったから
です。
特に1つ目について、去年のアドベントカレンダーで以下の記事を書きながらもJITについてあまり理解できていませんでした。現在と今後のRubyについて理解するために、今までのRubyについて知っておく必要があると思い、読もうと思っていました。
この本自体は日本語版の初版が2014年で、MRIのJITなどについての記述はなく、現在のRubyという意味でいうと少し古い内容になっている部分もありますが、今も変わらず活きている内容ばかりでした。
内容
章ごとに内容を軽くまとめてみます。
-第1章 字句解析と構文解析
Rubyがどのようにプログラムを解析するか
-第2章 コンパイル
解析したASTノードをYARVで実行する命令列にコンパイルする部分の説明。スタックや、変数等に関する情報を保存するローカルテーブルについて。
-第3章 Rubyはどのようにコードを実行するか
YARV命令実行時、内部スタック、コールスタックとの関係も1歩ずつ図示されている。異なるスコープの変数へのアクセス方法。
- 第4章 制御構造とメソッドディスパッチ
breakなどで別スコープへのジャンプする方法や、send
でのメソッドディスパッチなどについての説明もある
-第5章 オブジェクトとクラス
オブジェクトやクラスの構造体を見たり、インスタンスメソッドやインスタンス変数などの情報をどのように保存しているかが分かる
-第6章 メソッド探索と定数探索
継承やモジュールのincludeやprependをしたときにどのようにメソッドを探索するか、探索された結果をどうキャッシュするか。メソッド探索とは異なる、定数の探索方法。
-第7章 ハッシュテーブル:Ruby内部の働き者
様々な内部データの保存にも使われているハッシュテーブルについて。要素数が増えても素早く取得できる仕組みなど
- 第8章 Lispから借りてきたアイデア
ブロック、Procオブジェクトについて。Procオブジェクトが、スコープ外からローカル変数にアクセスできるように、メモリにどのように関数や環境を保存しておくか等についても説明されている。
- 第9章 メタプログラミング
メソッド定義における様々な方法。クロージャの概念を使ったメタプログラミング。
- 第10章 JRuby:JVM上のRuby
JRubyのコンパイル方法や、実行の最適化について
- 第11章 Rubinius:Rubyで実装されたRuby
MRIとの比較をしながらRubiniusの特徴について
- 第12章 MRI・JRuby・RubiniusにおけるGC
GCのアルゴリズムの比較
感想
- きちんとコンピュータサイエンスについて学んだことがなかったので、第1章から新鮮だった
- そのような人でも読める内容となっています(内容が易しいというわけではないですが)
- 「モジュールをincludeすると、モジュールで定義されているメソッドが使えるようになる」ような部分のメソッド探索についての理解が深まった
- Rubyが内部でモジュールやクラスの継承関係をどのように扱っていて、メソッド探索の際にその継承関係をどう遡っていくのかを知れた
- モジュールをインクルードした後にモジュールを変更する時の挙動がなるほど、と思った
- どのモジュールがメソッドテーブルを共有するのか、しないのか
- メソッドをオーバーライドするときなどに応用が効きそう
- クラスメソッドの定義方法もスコープの観点から理解できた
- レキシカルスコープのselfを知ること
- 点としては知っていたことが、つながったような感覚を何度か感じた
- Rubyオブジェクトの構造体や、メソッド探索、定数探索など
- 裏側を知ることで、知識が関連性を持った感覚
- ただ使うだけでなくて、どうしてそうなっているのかを知れた
- 処理系ごとに解決しようとしている課題が異なり、お互いに刺激しあっていて面白い
- JITを理解するヒントになったかも?
- YARVやスタックなどがどうなっているかを知った上で、JITではどこが変わるのかを改めて知りたい
- 改めてRubyのJITについての発表などを見返したい
- Rubyのコードを読むきっかけになった。少し読んでみると、執筆時点とコードが変わっているので、その変化についても知りたくなった
- Rubyについての理解が深まったので、他の言語を学ぶときにも、「Rubyではこうなっていたけど、この言語はどうなんだろう」のように考えるきっかけになりそう
まとめ
初心者向けではないですが、「普段Rubyを書くことはできているけど、どうしてそういう挙動をするのかを詳しく知りたい」という人におすすめです。
Ruby以外の背景知識が少なくても、詳しく図解されているので粘り強く読んでいけば理解できるはずです。
個人的には、また何度か読み返したいなと思いました。
WEBCAMP ENGINEER COMMUNITY のカレンダーを購読設定して、明日の記事もご覧いただけると嬉しいです。