在这个例子中
x = 1
foo = lambda do
x = 2
end
foo.call
foo会改变x的值。是否可以隐藏x的值,使其在proc调用之前和之后保持不变?
答案 0 :(得分:7)
我同意,如果你不知道确切的术语,它就不是非常可谷歌的。你走了:
x = 1
foo = lambda do
x = 2
end
foo.call
p x # => 2
x = 1
foo = lambda do |;x|
x = 2
end
foo.call
p x # => 1
自Ruby 1.9以来它已经可用,但我经常不会遇到它(如果有的话)。 它描述了here,它被称为"块局部变量"或者"块本地参数" :
您也可以使用';'来声明块的块本地参数。在里面 阻止参数列表。分配给块本地参数不会 覆盖调用者范围
中块之外的本地参数
@EliSadoff和@tadman在评论中提出了一个非常有效的观点。
有一个很好的理由阻止局部变量不经常使用:在块中隐藏外部变量通常不是一个好主意。它可能使代码更难阅读,更难理解并且更难使用。
使用Ruby块,外部和块变量通常是相关的,但不等同:
filename
作为外部变量,file
作为具有IO.open
的块变量array
作为外部变量,element
作为具有Array#each
的块变量strings
作为外部变量,string
作为具有Array#map
的块变量如果您需要bound variable且x
已被用作外部变量,请使用y
,i
,z
,{{1} },m
或n
。
答案 1 :(得分:3)
块不是闭包。
要实现您正在寻找的行为(获取对最外层变量的访问权并可以自由更改它),可以执行以下操作:
merged_df['title'].count()
目前还不清楚为什么不能对块局部变量使用相同的名称。
x = 1
foo = ->(y = x) { puts y; y = 2; puts y }
foo.()
puts x
#⇒ 1
# 2
# 1
我认为后者是ruby解释器中的错误。