【问题标题】:Static loop variable in Ruby 1.8.7Ruby 1.8.7 中的静态循环变量
【发布时间】:2015-06-11 19:27:47
【问题描述】:

我可能在这里用了一个误称。我希望在循环的第一次迭代中只设置一次变量,并保留之前迭代的值。
例如,如果未设置,我将变量值设置为 0。然后,根据迭代逻辑,值可以改变,在下一次迭代中,它将显示上一次迭代的值。
有什么想法吗?谢谢。

【问题讨论】:

    标签: ruby loops variables scope


    【解决方案1】:

    也许我不明白这个问题,你可以在循环之前设置变量,然后你可以修改里面的值。 如果你在循环外设置“var”,你可以在所有循环中修改和使用它。

    var, run = nil, true
    while run
      var = 1 unless var
      puts "IN: #{var}"
    
      if var > 1
        run = false
        break
      end
    
      var += 1
    end
    puts "OUT: #{var}"
    
    # => IN: 1
    # => IN: 2
    # => OUT: 2
    

    也许是这个?您可以使用 Proc.new,但之前是同一行。

    process = Proc.new{|var|
      var = 0 unless var # first set if nil
      puts "IN: #{var}"
      var
    }
    
    run, i = true, 0
    while run
      var = process.call(var)
      puts "After process: #{var}"
      break unless run = ( i < 2 )
      var += 1 # logic modify
      i += 1
    end
    
    puts "OUT: #{var}"
    
    # => [true, 0]
    # => IN: 0
    # => After process: 0
    # => IN: 1
    # => After process: 1
    # => IN: 2
    # => After process: 2
    # => OUT: 2
    

    【讨论】:

    • 嗨卢卡斯。这就是我所知道的。我想知道循环内是否有办法。我以为我已经在某个地方读到了在循环中执行此操作的方法,并将其保持在循环范围内。但我可能是错的。
    • @user1134991 我不知道,但这可能会有所帮助。或者您可以使用实例变量,但我找不到有关此问题的信息。所以也许它不是“简单”的方法。
    • 你为什么这么关心范围?这是一个循环。如果您在其中声明某些内容,则它会被限定范围,并且可能会根据使用的构造重置每次迭代。通过将其置于循环之外,您就是在声明您希望它在迭代之间持续存在的意图。
    【解决方案2】:

    这是另一种不做你想做的事的方法。

    b = binding
    3.times do |i|
      eval("foo = (foo.nil?) ? 10 : (foo+1)", b)
      eval("p foo", b)
      p binding
    end
    

    它不能像你想要的那样工作的根本原因是 Ruby 为每次循环创建一个新的绑定。除了使用外部绑定作为锚点之外,我想不出任何技巧。我使用外部绑定的 eval 接口只是为了说明。做同样事情的正确方法是在循环外声明一个变量,正如你已经知道的那样。

    10
    #<Binding:0x00000001708f40>
    11
    #<Binding:0x000000017089a0>
    12
    #<Binding:0x00000001708428>
    

    【讨论】:

    • 为什么需要eval 来处理这样的事情?闭包可以完成这项工作。这就像用手提钻打钉子一样。
    • 我并不是要暗示这是正确的做法。我试图说明每个循环迭代的新绑定是基本限制。同时表明使用外部静态绑定可以“解决”问题。是的,当然有更好的方法来附加到外部绑定。只是 eval 允许一个明确的附件来显示我的意思。
    • 鉴于问题围绕着避免必须在循环之外声明事物的方式展开,因此该测试也失败了。这是一种有趣的方法,但现在它应该出现在生产代码中。
    • 也许我的回复违反了 StackOverflow 的规则,因为它并不是一个解决方案。这是为了表明不存在解决方案。
    • 发布这样的答案是可以的。我只是认为如果他们听从你的建议,这会让人们走上危险的道路。
    猜你喜欢
    • 2021-02-24
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多