在JavaScript中,以下习语有时用于包含范围
// JavaScript
(function() {
var x = 0;
// do stuff
})(); // execute anonymous function in-place
// x is undefined (or its previous value)
你在Perl看到了这个:
{
local $/ = undef;
$file_contents = <FILE>;
}
# $/ == "\n"
Ruby中有类似的东西吗?我能想出的最接近的是:
Proc.new
x = 123
puts x
end.call
# x is undefined
还有另一种更常见的方法可以在Ruby中执行此操作,还是这样做最好?
答案 0 :(得分:5)
如果在块之前已经定义了x
,那么您的示例将无效:
x = 7
Proc.new do
x = 123
puts x
end.call
# x is now 123
Ruby允许您使用这种相当模糊的语法在块参数列表中指定块局部变量:
x = 7
Proc.new do |;x| # declare x as block local
x = 123
puts x
end.call
# x is still 7
;
之后的任何变量都被视为该块的本地变量,并且不会在封闭范围内影响类似命名的变量。
答案 1 :(得分:0)
最近的解决方案是使用stabby lambda表示法:
-> {
x = 123
puts x
}.call
Ruby在这种情况下使用匿名过程并不常见。我能想到的最红宝石的方式是将每个试验都放在小巧轻便的课堂上。
答案 2 :(得分:0)
使用proc
proc {
...
}[]
已经很小了,虽然不是很惯用。您可以编写自己的包装器,您可能会发现它更优雅,因为它避免了创建匿名函数
def wrap
yield
end
wrap do
...
end
但是,正如@matt指出的那样,这并不妨碍您访问在块外定义的变量。