当调用`next`时,每次'每次'迭代后回调

时间:2016-05-12 17:14:18

标签: ruby

我想在each的每次迭代后运行一些代码。有没有办法在不重复代码的情况下执行此操作?我试过这个:

(1..10).each do |n|
  continue = Proc.new {
    puts "ended #{n}"
    next
  }
  continue.call if n == 2
  puts n
  continue.call
end

但它不起作用。

在我的实际代码中,我有很多next次调用。这就是为什么每次调用next时调用方法都是不切实际的。

4 个答案:

答案 0 :(得分:1)

方法1

在循环调用的方法中定义循环的内容。您可以在方法中放置ensure块。这样,您的方法可以在任何想要移动到下一次迭代的地方使用return,但您仍然可以保证执行ensure代码:

def doit(x)
  return if x == 2
  puts "I like the number #{x}"
ensure
  puts "LOOP"
end

[1,2,3,4].each{|x| doit(x)}

结果

I like the number 1
LOOP
LOOP
I like the number 3
LOOP
I like the number 4
LOOP

方法2

与方法1类似,但允许您重复使用"回调"不同问题的代码。它还可以让您使用next代替return。这是为了定义yield s然后做其他事情的方法:

def ensure_LOOP(x)
  yield
  puts "LOOP"
end

[1,2,3,4].each do |x|
  ensure_LOOP(x) do
    next if x == 2
    puts "I really like the number #{x}"
  end
end

结果

I really like the number 1
LOOP
LOOP
I really like the number 3
LOOP
I really like the number 4
LOOP

[1,2,3,4].each do |x|
  ensure_LOOP(x) do
    next unless x == 2
    puts "I don't like the number #{x}"
  end
end

结果

LOOP
I don't like the number 2
LOOP
LOOP
LOOP

答案 1 :(得分:0)

只需在每个循环中调用它吗?

(1..10).each do |n|
  puts n
  puts "ended #{n}"
end

答案 2 :(得分:0)

您实际提供的代码 运行,并输出以下内容:

1
ended 1
ended 2
2
ended 2
3
ended 3
4
ended 4
5
ended 5
6
ended 6
7
ended 7
8
ended 8
9
ended 9
10
ended 10

正如您所看到的,Proc会因为if条件在这种情况下通过而调用Proc而被调用两次。

退一步,在迭代的上下文中定义之外的方法可能是更好的选择。它将使代码更易于阅读,并避免每次Proc块执行时重新定义each

那就是说,从技术上讲,你在这里看起来似乎运行良好。

答案 3 :(得分:0)

据我了解这个问题,如果continue.call n==2之后你不想要执行任何操作。如果这是正确的,您可以将控制表达式next与参数一起使用。

def m(n)
  puts "Only #{n} more days!"
end

(1..6).each do |n|
  next m(n) if n==3
  puts n
  m(n)
end
1
Only 1 more days!
2
Only 2 more days!
Only 3 more days!
4
Only 4 more days!
5
Only 5 more days!
6
Only 6 more days!