块中的局部变量

时间:2016-12-28 16:47:06

标签: ruby lambda

在这个例子中

x = 1

foo = lambda do
  x = 2
end

foo.call

foo会改变x的值。是否可以隐藏x的值,使其在proc调用之前和之后保持不变?

2 个答案:

答案 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 variablex已被用作外部变量,请使用yiz,{{1} },mn

答案 1 :(得分:3)

块不是闭包。

要实现您正在寻找的行为(获取对最外层变量的访问权并可以自由更改它),可以执行以下操作:

merged_df['title'].count()

目前还不清楚为什么不能对块局部变量使用相同的名称。

x = 1
foo = ->(y = x) { puts y; y = 2; puts y }
foo.()
puts x
#⇒ 1
#  2
#  1

我认为后者是ruby解释器中的错误。