你基本上是試圖做到這一點:
myfunc = lambda {puts eval("word"), eval("x")}
words = ["teacher", "songwriter", "producer"]
words.each do |word|
x = 10
myfunc.call
end
但Word和x的每()塊的局部變量,因此拉姆達塊不能看到它們。塊可以看到他們的封閉範圍 - 但他們不能看到其封閉範圍內包含的其他範圍內。這工作:
myfunc = lambda {puts eval("word"), eval("x")}
word = "hello"
x = 10
myfunc.call
--output:--
hello
10
這裏是一個更有趣的版本:
func1 = lambda {puts eval "x"}
func2 = lambda {puts x}
x = "hello"
func1.call
func2.call
--output:--
hello
1.rb:23:in `block in <main>': undefined local variable or method `x' for main:Object (NameError)
from 1.rb:27:in `call'
from 1.rb:27:in `<main>'
它看起來像EVAL綁定()比關閉第二塊「大」:爲EVAL綁定( )是塊外的整個封閉範圍;但由第二個塊形成的閉包只關閉了創建塊時封閉範圍內的變量。
這似乎很有道理在這個例子中的光:
b = binding
myfunc = lambda {puts eval("word", b), eval("x", b)}
word = "hello"
x = 10
myfunc.call
--output:--
hello
10
所以,當你寫:
myfunc = lambda {puts eval("word"), eval("x")}
word = "hello"
x = 10
myfunc.call
...就好像在lambda塊被關閉了一個無形的b變量提供,該eval()默認使用,然後代碼基本上這樣做:b.word = "hello"; b.x = 10
。這作品在這裏以同樣的方式:
word = nil
x = nil
myfunc = lambda {puts word, x}
word = "hello"
x = 10
myfunc.call
--output:--
hello
10
換句話說,一個塊關閉了變數 - 沒有價值觀,一個塊關閉了可通過該塊後到來代碼被改變的變量。
Does anyone know another ways to pass var name and var value via one param?
有可容納多於一個的數據塊許多紅寶石對象:陣列,散列,結構,自定義類的實例,等
valid_specs = ["instrumentalist", "dj", "producer", "songwriter", "teacher"]
validate_obj = lambda do |data|
obj_name = data.var_name
obj = eval obj_name, data.binding
p "no such #{obj_name} `#{obj}`" unless valid_specs.include? obj
end
MyData = Struct.new(:var_name, :binding)
specs = ["teacher", "sweeper", "producer"]
specs.each do |spec_id|
mydata = MyData.new("spec_id", binding)
validate_obj.call(mydata)
end
--output:--
"no such spec_id `sweeper`"
但是,代碼也可以寫入更只是這樣:
valid_specs = ["instrumentalist", "dj", "producer", "songwriter", "teacher"]
validate_obj = lambda do |spec_id|
p "no such spec_id `#{spec_id}`" unless valid_specs.include? spec_id
end
specs = ["teacher", "sweeper", "producer"]
specs.each do |spec_id|
validate_obj.call(spec_id)
end
也許不是那麼美麗,但完全工作的解決方案,我一直在尋找。我也採用了簡短的語法(' - >'='lambda'和'.' ='.call')。有誰知道另一種通過一個參數傳遞var name和var value的方法嗎? –
@RubyLover除了「作弊」並且在一個對象中包含兩個對象(例如傳遞一個包含兩個對象的數組)之外,還有* no *方法只用一個參數來完成。 –