メタプログラミングRuby読みメモ 5
6章 コードを記述するコード
Kernel#eval
Kernel#eval
は、ブロックではなくRubyのコードの文字列を受け取る- これをコード文字列と呼ぶ
- eval は渡されたコード文字列を実行する
- instance_evalとclass_evalもブロックだけでなく、コード文字列も受け取れる
Bindingオブジェクト
- Binding はスコープをまとめたもの
- Binding を使ってローカルスコープを取得すればそのスコープを持ち回すことができる
Kernel#binding
メソッドで生成できる- スコープを持っているため、evalでBindingオブジェクトに渡すことでそのスコープでコードを評価できる
- すごい!こんな仕組みだったんだ
- pryというgemにはオブジェクトのスコープでインタラクティブセッションを開く
Object#pry
メソッドが定義されている - これを用いてbindingのpryを呼び出すことでデバッガのように使うことができる
irb
- irbは標準入力やファイルをパースして、それぞれの行をevalに渡すプログラム
- こうしたプログラムはコードプロセッサと呼ばれる
eval の問題点
- コード文字列はシンタックスハイライトが効かない
- 外部からのコード文字列を受け取るとコードインジェクションの危険がある
オブジェクトの汚染とセーフレベル
- 潜在的に安全ではないオブジェクトに自動的に汚染の印がつく
- 汚染オブジェクトには、ウェブフォーム、ファイル、コマンドライン、システム変数、プログラムが読み込んだ文字列などが含まれる
- 汚染された文字列を操作して新しい文字列を作ると、その新しい文字列も汚染される
- taind?メソッドで確認できる
- Ruby はセーフレベルを設定できる
- セーフレベルが0より大きいと汚染した文字列を評価できない
フックメソッド
- イベントをキャッチできるメソッド
Class#inherited
は継承されたときに実行してくれるメソッド- デフォルトでは何もしないのでオーバーライドして使う
Module#included
やModule#prepended
でモジュールのライフサイクルにプラグインできるModule#extended
でモジュールを拡張したときに入り込める- 特異メソッドをキャッチするときには
Kernel#singleton_method_added
などを使う