Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python的Ruby等价非局部_Python_Ruby_Closures_Python Nonlocal - Fatal编程技术网

python的Ruby等价非局部

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

我正在尝试用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
    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