Rubyのしくみ Ruby Under a Microscope株式会社 オーム社, 2014/11/29 - 408 ページ もっと知りたい、Rubyのしくみ VMベースのインタプリタ型言語処理系であるRubyがコードを 実務でRubyは使えるけれど、 Rubyインタプリタを題材にプログラミング言語処理系の仕組み 日本語版には、 日本語版序文 |
目次
第1章字句解析と構文解析 | 3 |
Rubyを構成する言葉 | 4 |
parser_yylex関数 | 7 |
Ripperを使ってさまざまなRubyスクリプトを字句解析する | 9 |
Rubyはコードをどのように理解するか | 12 |
LALR構文解析アルゴリズムを理解する | 14 |
実際のRubyの文法規則をいくつか | 21 |
Bisonの文法規則を読む | 23 |
Rubyはハッシュ関数をどう実装しているか | 202 |
ハッシュのキーとしてオブジェクトを使用する | 205 |
Ruby 20におけるハッシュ最適化 | 210 |
まとめ | 211 |
第8章 Lispから借用したアイデア | 213 |
Rubyにおけるクロージャ | 214 |
Rubyのブロック呼び出しを一歩ずつ確認する | 215 |
1975年から借用したアイデア | 218 |
Ripperを使ってさまざまなRubyスクリプトを構文解析する | 25 |
まとめ | 31 |
第2章コンパイル | 33 |
Ruby18にコンパイラはない | 34 |
Ruby19以降はコンパイラを導入する | 35 |
単純なスクリプトをRubyはどうコンパイルするか | 36 |
ブロック呼び出しのコンパイル | 41 |
RubyはASTの中をどう反復していくか | 45 |
YARV命令を表示する | 48 |
ローカルテーブル | 49 |
オプション引数のコンパイル | 52 |
キーワード引数のコンパイル | 54 |
ローカルテーブルを表示する | 56 |
まとめ | 58 |
第3章 Rubyはどのようにコードを実行するか | 61 |
YARVの内部スタックとRubyのコールスタック | 62 |
Rubyが単純なスクリプトをどう実行するかを見ていく | 63 |
ブロック呼び出しの実行 | 66 |
YARV命令を間近に見てみる | 68 |
Ruby20Ruby19とRuby18のベンチマーク比較 | 71 |
Ruby変数のローカルアクセスと動的アクセス | 74 |
メソッド引数はローカル変数とみなされる | 77 |
動的変数アクセス | 78 |
Cの世界でEPのはしごを上る | 81 |
特殊変数を調査する | 83 |
特殊変数リストの決定版 | 87 |
まとめ | 89 |
第4章制御構造とメソッドディスパッチ | 91 |
Rubyがどうやってif文を実行するか | 92 |
あるスコープから別のスコープへジャンプする | 95 |
捕捉テーブル | 96 |
捕捉テーブルの別の利用方法 | 98 |
Rubyがループを内部でどう実装しているかをテストする | 99 |
Rubyで最も複雑な制御構造 | 101 |
11種類のメソッドタイプ | 102 |
通常のメソッド呼び出し | 104 |
通常のメソッド向け引数の準備 | 105 |
組み込みメソッド呼び出し | 106 |
attr_readerとattr_writerの呼び出し | 107 |
attr_readerとattr_writerにおけるメソッドディスパッチの最適化 | 108 |
Rubyがキーワード引数をどう実装しているかの調査 | 109 |
まとめ | 113 |
第5章オブジェクトとクラス | 115 |
Rubyオブジェクトの内側 | 116 |
klassとivptrの調査 | 117 |
クラスの2つのインスタンスの可視化 | 118 |
一般的なオブジェクト | 119 |
単純なRubyの値は構造体を全く必要としない | 120 |
一般的なオブジェクトはインスタンス変数を持つか? | 121 |
RBasic構造体とRObject構造体の定義を読む | 122 |
Rubyは一般的なオブジェクト用のインスタンス変数をどこに保存するか? | 123 |
新しいインスタンス変数を保存するのにどれくらい時間がかかるか? | 124 |
RClass構造体の内側は何? | 127 |
継承 | 130 |
クラスインスタンス変数vsクラス変数 | 132 |
クラス変数の取得と設定 | 134 |
定数 | 137 |
実際のRClass構造体 | 138 |
RClass構造体の定義を読む | 140 |
Rubyはクラスメソッドをどこに保存する? | 141 |
まとめ | 144 |
第6章メソッド探索と定数探索 | 147 |
Rubyがモジュールをどう実装しているか | 148 |
クラスにモジュールをインクルードする | 150 |
Rubyのメソッド探索アルゴリズム | 151 |
メソッド探索の例 | 152 |
実際のメソッド探索アルゴリズム | 154 |
Rubyにおける多重継承 | 156 |
インラインメソッドキャッシュ | 157 |
Rubyのメソッドキャッシュをクリアする | 158 |
あるモジュールを別のモジュールにインクルードする | 160 |
Moduleprependの例 | 162 |
RubyがModuleprependをどう実装しているか | 166 |
インクルードした後でモジュールを変更する | 167 |
クラスはモジュールのメソッドを後で確認する | 168 |
クラスはインクルードされたサブモジュールを後では確認しない | 169 |
インクルードされたクラスは元のモジュールとメソッドテーブルを共有する | 170 |
Rubyがモジュールをどうコピーしているかを詳しく見る | 171 |
定数探索 | 173 |
Rubyはどうやって親の名前空間内の定数を見つけるか? | 175 |
Rubyにおけるレキシカルスコープ | 176 |
新しいクラスやモジュール用に定数を生成する | 177 |
レキシカルスコープを使って親の名前空間内の定数を見つける | 179 |
Rubyの定数探索アルゴリズム | 181 |
Rubyはどの定数をはじめに見つけるのか? | 182 |
Rubyの実際の定数探索アルゴリズム | 183 |
まとめ | 184 |
Ruby内部の働き者 | 187 |
Rubyにおけるハッシュテーブル | 188 |
ハッシュテーブルから値を取り出す | 191 |
さまざまなサイズのハッシュテーブルから値を取り出す | 192 |
ハッシュテーブルを拡張してより多くの値を格納する仕組み | 194 |
ハッシュの衝突 | 195 |
エントリの再ハッシュ | 196 |
さまざまなサイズのハッシュに新しい要素を1つ追加する | 197 |
マジックナンバー57と67はどこからくるのか? | 200 |
rb_block_tとrb_control_frame_t構造体 | 221 |
whileループとeachにブロックを渡すのとどちらが速いか | 222 |
関数を第一級市民として扱う | 226 |
スタックvsヒープメモリ | 227 |
Rubyが文字列の値をどう保存するかを詳しく見る | 228 |
Rubyはラムダをどう作るか | 230 |
Rubyはラムダをどう呼び出すか | 233 |
Procオブジェクト | 235 |
ラムダを呼び出した後でローカル変数を変更する | 238 |
同じスコープでラムダを1回以上呼び出す | 241 |
まとめ | 243 |
第9章メタプログラミング | 245 |
メソッドを定義する別のやり方 | 246 |
オブジェクトのプレフィックスを使ってクラスメソッドを定義する | 248 |
新しいレキシカルスコープを使ってクラスメソッドを定義する | 250 |
特異クラスを使ってメソッドを定義する | 251 |
レキシカルスコープ内の特異クラスを使ってメソッドを定義する | 253 |
Refinementsを作成する | 254 |
Refinementsを使用する | 256 |
わたしは誰? レキシカルスコープを使うとselfはどう変わるか | 257 |
トップレベルスコープでのself | 258 |
クラススコープでのself | 259 |
メタクラススコープでのself | 260 |
クラスメソッドの内側でのself | 261 |
evalinstance_evalbinding | 263 |
bindingと共にevalを呼び出す | 266 |
instance_evalを使う例 | 268 |
Rubyのクロージャにおけるもう1つの重要な側面 | 269 |
instance_evalはselfをレシーバに変更する | 271 |
instance_evalは新しいレキシカルスコープ用に特異クラスを作成する | 272 |
ブロック用のレキシカルスコープをRubyはどう監視し続けるか | 273 |
メソッドを定義するためにクロージャを使う | 275 |
メソッドはクロージャとして機能する | 276 |
まとめ | 278 |
JVM上のRuby | 281 |
MRIとJRubyでプログラムを実行する | 282 |
JRubyはコードをどうパースしコンパイルするか | 284 |
JRubyはコードをどう実行するか | 285 |
RubyクラスをJavaクラスを使って実装する | 288 |
JRubyのJITコンパイラを観察する | 290 |
実験コード | 291 |
+PrintCompilationオプションの使用 | 292 |
JITはJRubyプログラムを高速化するか | 293 |
JRubyとMRIにおける文字列 | 295 |
コピーオンライト | 297 |
コピーオンライトの性能を計測する | 300 |
実験コード | 302 |
共有文字列を編集することは速度を落とす | 304 |
まとめ | 305 |
Rubyで実装されたRuby | 309 |
Rubiniusカーネルと仮想マシン | 310 |
字句解析と構文解析 | 312 |
Rubyを使ってRubyをコンパイルする | 313 |
RubyとC++とで一緒に動く | 315 |
RubyのオブジェクトをC++オブジェクトで実装する | 317 |
Rubiniusのバックトレース | 318 |
RubiniusとMRIの配列 | 321 |
RArray構造体の定義 | 323 |
Rubiniusの配列の内側 | 324 |
RubiniusのArrayshiftの実装を調査する | 325 |
Arrayshiftを読む | 326 |
Arrayshiftを変更する | 327 |
まとめ | 330 |
第12章 MRIJRubyRubiniusにおけるGC | 333 |
ガベージコレクションは3つの問題を解決する | 334 |
MRIの複数のフリーリストの用途 | 335 |
マーク | 336 |
MRIは生きているオブジェクトをどうマークするか | 337 |
スイープ | 338 |
遅延スイープ | 339 |
マークスイープのデメリット | 340 |
MRIの遅延スイープの様子を見る | 342 |
MRIのフルGCを見る | 343 |
GCのプロファイリングレポートを翻訳する | 344 |
JRubyとRubiniusにおけるGC | 348 |
バンプアロケーション | 349 |
半空間アルゴリズム | 350 |
Edenヒープ | 352 |
弱い世代別仮説 | 353 |
旧世代オブジェクト用のガベージコレクション | 354 |
世代間の参照 | 355 |
並行GC | 357 |
三色マーキング | 359 |
JVMにおける3つのGC | 360 |
JRubyのVerbose GCモードを使う | 362 |
メジャーGCを始動する | 363 |
参考文献 | 365 |
付録A さらにそのほかのRuby仮想マシン | 369 |
YARVの設計方針 | 370 |
YARVの開発までの経緯 | 371 |
さらにそのほかのRuby仮想マシン | 372 |
訳者あとがき | 373 |
375 | |
著者訳者について | 382 |
奥付 | 383 |