メタプログラミング 第四章 ブロック
ブロック
ブロックは {} もしくは do endキーワードで定義出来ます。 具体例を説明します。
["1","2","3"].each do |i| puts i end # => ["1", "2", "3"]
文法書でよくある記述ですが、ブロックの前(do endキーワード) の前には 配列オブジェクト そして メソッド(eachメソッド) を用いて配列を標準出力しています。
処理の流れとしてはブロックをメソッドに渡してオブジェクトとメソッドで処理を行っています。
ここで注意したいのはブロックは単体では存在できず、メソッドの引数となることです。
またメソッドの引数を理解するには以下の例も参考になると思います。
def block_test yield end block_test do p "block_test" end # "block_test"
これはblock_test でメソッドを定義して、 yieldキーワードで書かれたメソッドにブロックを実行した例です。
クロージャ
クロージャの定義はある関数が作られた時に状態(ローカル変数、インスタンス変数) が関数内で保持されることです。
そしてブロックはクロージャです。
次のコードを見て下さい。
def test_method x = "hoge" yield end x = "hogehoge" test_method do p x end #hogehoge
上記の例を見ると、出力されるのは “hoge"という気がしますが、 実行すると、"hogehoge"が出力されます。
これはどういうことかというと ブロックはメソッドの引数となり、 ブロックが定義された段階では xはローカル変数(hogehoge)と認識しているためです。