tnodaの日記: 「メタプログラミング Ruby 」読書ノート - 第3章 水曜日: ブロック
今日 Ruby について学んんだこと:
(1) スコープ
(2) クリーンルーム
(3) Proc オブジェクトを用いた遅延評価
(1) スコープ
--------------------
* スコープゲート
- class/module/def
* フラットスコープ
- スコープゲートをメソッドで置き換えれば、スコープゲートが無くなる
=> フラットスコープ
- class => Class.new()
- module => Module.new()
- def => Module#define_method()
- 共有スコープ = 複数メソッドで変数を有効にしたいとこは、
すべてのメソッドを同じフラットスコープに変数として定義すればよい
(2) クリーンルーム
--------------------------
* instance_eval()
- オブジェクトのコンテキストでブロックを評価
= オブジェクト探査機
- プライベートメソッドやインスタンス変数にアクセスできる
- ブロックに引数を渡したいときには、instance_exec()
* クリーンルーム
- ブロックを評価するためだけに生成するオブジェクト
clean_room.instance_eval() do
...
end
(3) Proc オブジェクトを用いた遅延評価
---------------------------------------------------------
* &修飾 (変数名の前に & をつける)
- メソッドの特別な引数 = 引数列の最後、かつ名前の前に & をつけるとブロック
- Proc オブジェクトに & をつけるとブロック
def foo(a, b, &block)
block #=> Proc オブジェクト
bar(a, b, &block) #=> 前に & をつけるとブロック
* lambda との違い: ジャッジメントですの
- return の扱いが異なる
lambda のリターン => lambda から戻る
Proc のリターン => Proc が定義されたスコープから戻る
- 引数の扱い
lambda のほうが厳しい
そのほか
---------------
* ブロックの基本
- 束縛、クロージャ、スコープ
- メソッド内部では、Kernel#block_given?() メソッドでブロック有無を確認
=> true なら yield でブロックをコールバックできる
- Ruby 1.8 では、ブロック引数が同名のローカル変数を書き換えていた
=> Ruby 1.9 では書き換えない
* グローバル変数とトップレベル (main) のインスタンス変数
- グローバル変数はプログラム全域からアクセス可
- トップレベルのインスタンス変数は self が main となる場所でのみアクセス可
「メタプログラミング Ruby 」読書ノート - 第3章 水曜日: ブロック More ログイン