python的Ruby等价非局部
我正在尝试用Ruby编写一个闭包。这是用Python编写的代码:python的Ruby等价非局部,python,ruby,closures,python-nonlocal,Python,Ruby,Closures,Python Nonlocal,我正在尝试用Ruby编写一个闭包。这是用Python编写的代码: def counter(): x = 0 def increment(y): nonlocal x x += y print(x) return increment Ruby中是否有一个“非本地”等价物,以便我可以从increment内部访问并更改变量x?可能类似于: class CGroup def counter @x ||= 0 l
def counter():
x = 0
def increment(y):
nonlocal x
x += y
print(x)
return increment
Ruby中是否有一个“非本地”等价物,以便我可以从increment内部访问并更改变量x?可能类似于:
class CGroup
def counter
@x ||= 0
lambda do |y|
@x += y
end
end
end
然后:
我不知道Python的非本地
的直接模拟
编辑:实例变量是不必要的,使用方法的局部变量也可以实现同样的效果。这使得类变得多余,尽管Ruby中的许多内容发生在对象的上下文中。既然有人反对使用对象,为什么不使用lambda呢
counter_generator = ->(){
x ||= 0
->(y){
x += y
puts x
}
}
i = counter_generator.call
=> #<Proc:0x00000100867508@(irb):17 (lambda)>
i.call(1)
1
=> nil
i.call(1)
2
=> nil
计数器\u生成器=->(){
x | |=0
->(y){
x+=y
放x
}
}
i=计数器\生成器调用
=> #
i、 电话(1)
1.
=>零
i、 电话(1)
2.
=>零
请注意,incrementor实际上返回nil,因为您只指定了输出x的值,而不是返回它。非局部关键字告诉Python要捕获哪些变量。在Ruby中,您不需要这样的关键字:除非另有明确说明,否则所有变量都被捕获 因此,相当于Python代码的Ruby几乎可以直接翻译:
counter = -> {
x = 0
->y {
x += y
puts x
}
}
i = counter.()
i.(2)
# 2
i.(3)
# 5
对于计数器
,使用方法可能更为惯用,不过:
def counter
x = 0
->y {
x += y
puts x
}
end
i = counter
i.(2)
# 2
i.(3)
# 5
这会创建一个完全不必要的对象。@delnan:同意。我不喜欢它。我们的想法是通过使用globals来避免名称空间污染。注意,要实现与问题中的函数(返回的函数是独立的)非常类似的任何功能,您必须避免使用globals。非常感谢!大多数在线闭包示例只使用lambdas来创建新函数,因此我不确定如何创建保持某种状态的闭包。很高兴提供帮助。您可以在任何ruby方法中使用
计数器生成器
的主体,无论是方法、proc还是lambda,其工作原理都是一样的。外部lambda不是很重要,它只是节省了一些输入。
def counter
x = 0
->y {
x += y
puts x
}
end
i = counter
i.(2)
# 2
i.(3)
# 5