如何编写内联块以包含Ruby中的局部变量范围?

时间:2014-04-01 14:53:06

标签: ruby

在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中执行此操作,还是这样做最好?

3 个答案:

答案 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指出的那样,这并不妨碍您访问在块外定义的变量。