【发布时间】:2015-06-11 19:27:47
【问题描述】:
我可能在这里用了一个误称。我希望在循环的第一次迭代中只设置一次变量,并保留之前迭代的值。
例如,如果未设置,我将变量值设置为 0。然后,根据迭代逻辑,值可以改变,在下一次迭代中,它将显示上一次迭代的值。
有什么想法吗?谢谢。
【问题讨论】:
标签: ruby loops variables scope
我可能在这里用了一个误称。我希望在循环的第一次迭代中只设置一次变量,并保留之前迭代的值。
例如,如果未设置,我将变量值设置为 0。然后,根据迭代逻辑,值可以改变,在下一次迭代中,它将显示上一次迭代的值。
有什么想法吗?谢谢。
【问题讨论】:
标签: ruby loops variables scope
也许我不明白这个问题,你可以在循环之前设置变量,然后你可以修改里面的值。 如果你在循环外设置“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
【讨论】:
这是另一种不做你想做的事的方法。
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 来处理这样的事情?闭包可以完成这项工作。这就像用手提钻打钉子一样。