Created
January 10, 2015 23:41
-
-
Save lnznt/6c3641f4a9fce40aaa4a to your computer and use it in GitHub Desktop.
Ruby: Binding ref: http://qiita.com/lnznt/items/4c3e1050dafd59193808
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
a = 10 | |
p [1,2,3].map {|n| n * a } #=> [10, 20, 30] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
a = 10 # main に変数`a`を定義する。 | |
f1 = -> { a * 2 } # クロージャは変数`a`を包む。`a`の参照するオブジェクト「`10`」を包むのではない | |
a = 100 # 変数`a`の参照するオブジェクトを変更 | |
p f1.() #=> 200 # クロージャ実行時に`a`が参照するオブジェクト「`100`」を評価 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
v = 10 | |
# instance_eval は self をレシーバにしてブロックを評価する | |
instance_eval do # ここでは、レシーバが self なので self を self にしている。 | |
a = 1 # ブロック内(ダイナミックスコープ)の変数 | |
b = 2 # ブロック内(ダイナミックスコープ)の変数 | |
p a #=> 1 | |
p b #=> 2 | |
p v #=> 10 # ブロック外(レキシカルスコープ)の変数 | |
end | |
p v #=> 10 | |
p a # エラー! (NameError: undefined local variable or method `a' ...) | |
p b # エラー! (NameError: undefined local variable or method `b' ...) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
f2 = -> { b * 2 } # 変数`b`はブロック内の変数 | |
b = 1000 # main に変数`b`を定義する。しかし、ブロック内の変数`b`とは別物。 | |
# さらに、クロージャ定義時にはこの変数は定義されてないので、クロージャに包まれていない。 | |
p f2.() # NameError: undefined local variable or method `b' for main:Object 。。。(;_;) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
g = -> { a = 10 ; -> { a * 2 } } # g は関数 (-> { a * 2 }) を返す高階関数 | |
f = g.() | |
f.() #=> 20 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
g = -> { count = [] ; -> { count << :x } } | |
f1 = g.() # f1 のコール f2 のコール | |
f1.() #=> [:x] # 1回目 | |
f1.() #=> [:x, :x] # 2回目 | |
f1.() #=> [:x, :x, :x] # 3回目 | |
f2 = g.() | |
f2.() #=> [:x] # 1回目 | |
f2.() #=> [:x, :x] # 2回目 | |
f1.() #=> [:x, :x, :x, :x] # 4回目 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
b1 = f1.binging | |
p b1.class #=> Binding |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
p b1.local_variable_get(:count) #=> [:x, :x, :x, :x] | |
b1.local_variable_set(:count, []) # カウンタをリセットしてみる | |
p f1.() #=> [:x] | |
p f1.() #=> [:x, :x] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Binding | |
alias [] local_variable_get | |
alias []= local_variable_set | |
end | |
g = -> { a = 0 ; -> { a += 1 } } | |
f = g.() | |
f.() #=> 1 | |
f.() #=> 2 | |
f.() #=> 3 | |
b = f.binding | |
p b[:a] #=> 3 | |
b[:a] = 10 # 変数`a` の値を 10 にする | |
f.() #=> 11 | |
f.() #=> 12 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
g = -> { a = 10; -> { x = 2; a * 2 } } | |
f = g.() | |
b = f.binding | |
b.local_variable_get :a #=> 10 | |
b.local_variable_get :x # エラー (NameError: local variable `x' not defined for #<Binding:...) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
obj = Object.new | |
b = obj.send(:binding) # private メソッドだが、send でなら呼び出せる | |
p b.class #=> Binding |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment