Ruby でクロージャ
クロージャってブロックとしてよく使っているが、何者なのかよくわかってなかった。
急に気になったので調べてみた。ただし Wikipedia。
クロージャ - Wikipedia
典型的には、クロージャはある関数全体が他の関数(以下、エンクロージャ)の内部で宣言されたときに発生し、内部の関数はエンクロージャのローカル変数(レキシカル変数)を参照する。実行時に外部の関数が実行された際、クロージャが形成される。クロージャは内部の関数のコードとエンクロージャのスコープ内の必要なすべての変数への参照からなる。
内部で宣言された関数は、宣言を行った関数内のローカル変数を参照できるってことかね。
サンプルコード
Wikipedia に 載ってた Javascript のカウンタを Ruby で書いてみた。
#!/usr/bin/env ruby def count i = 0 lambda {i += 1} end c1 = count 5.times do |i| puts c1.call end # >> 1 # >> 2 # >> 3 # >> 4 # >> 5
ちなみに関数の引数を利用することもできる。
#!/usr/bin/env ruby def count i lambda {i += 1} end c1 = count 0 5.times do |i| puts c1.call end
サンプルその2
これは間違いっぽい。
呼び出した関数のローカル変数ではなく、クラス内に値を保持してしまっているから。
やってることは似てるけど。
#!/usr/bin/env ruby class Hoge def initialize @x = 0 end def count return lambda{ @x += 1 } end end h = Hoge.new 5.times do |i| puts h.count.call end