在Javascript中,IIFE(即时调用函数表达式,尽管可能有其他扩展的缩写)可以写成:
(function () {
var foo = 'bar'
console.log('hi!');
})();
其中变量声明foo
不会污染当前范围。我怎样才能在Ruby文件中做同样的事情?
我想在约束范围内创建一些临时变量(带闭包),并使文件中的其他代码无法访问它们。
答案 0 :(得分:3)
defined?(foo)
# => nil
# This defines a lambda, i.e. a closure with its own variable scope, among other things
# and directly executes it
lambda {
foo = 'bar'
puts foo
}.()
defined?(foo)
# => nil
在这个例子中,我们首先检查是否定义了变量foo
,而不是。然后,我们创建一个新的lambda对象(在Ruby中是一种特殊的Proc。并直接执行它。
Proc继承周围范围的变量,以便在proc中也可以访问(和更改)已定义的所有局部变量。但是,proc中定义的新变量只在proc之外不可见。
这可以通过最终的defined?
声明进行验证。
请注意,这种技术不是很像红宝石。相反,您应该创建可以随后调用的实际方法。为了封装数据和行为,您还可以创建小类,即使是一次性使用,它也能完全处理您的行为和所有必需的数据。
通常在Ruby中,你倾向于不传递匿名闭包(即javascript中的匿名函数或Ruby中的procs / lambdas / blocks)但是使用完整对象。如果您经常在代码中使用上述技术,那么您将从经验丰富的ruby开发人员那里获得有关的一瞥。
答案 1 :(得分:2)
好吧,你也是这样做的:写一个任意的lambda文字,并立即调用它。
但有一点需要注意:Ruby没有变量声明。因此,在块内部也存在块内的变量名称的使用是指捕获的外部变量,而在ECMAScript中,如果在函数内声明void TabletWidget::mousePressEvent(QMouseEvent *event)
{
if (!_deviceActive)
qDebug() << "mousePressEvent";
}
,它将遮蔽外部变量{{1} }。
如果你想在Ruby中使用相同的行为,你必须在块的参数列表中显式声明var foo
作为块局部变量:
foo
如果不这样做,则块内的赋值将修改捕获的外部绑定。比较:
foo
如您所见,外部绑定已被修改。
-> (;foo) do
foo = 'bar'
puts 'hi!'
end.()
如您所见,只有第二个实际匹配ECMAScript版本:
foo = 'foo'
-> do
foo = 'bar'
puts 'hi!'
end.()
foo
# => 'bar'