如何从红宝石块中跳出来?

这里是Bar#do_things

class Bar   
  def do_things
    Foo.some_method(x) do |x|
      y = x.do_something
      return y_is_bad if y.bad? # how do i tell it to stop and return do_things? 
      y.do_something_else
    end
    keep_doing_more_things
  end
end

这里是Foo#some_method

class Foo
  def self.some_method(targets, &block)
    targets.each do |target|
      begin
        r = yield(target)
      rescue 
        failed << target
      end
    end
  end
end

我想过使用raise,但我试图使它成为泛型,所以我不想在Foo任何具体的东西。


使用关键字next 。 如果你不想继续下一个项目,请使用break

当下next在块内使用时,会导致块立即退出,并将控制返回到迭代器方法,然后可以通过再次调用块来开始新的迭代:

f.each do |line|              # Iterate over the lines in file f
  next if line[0,1] == "#"    # If this line is a comment, go to the next
  puts eval(line)
end

当在块中使用时, break将控制移出块,从调用块的迭代器中移出,并在调用迭代器之后移至第一个表达式:

f.each do |line|             # Iterate over the lines in file f
  break if line == "quitn"  # If this break statement is executed...
  puts eval(line)
end
puts "Good bye"              # ...then control is transferred here

最后,在块中使用return

return总是导致封闭的方法返回,无论嵌套在块中的嵌套深度如何(lambda表达式除外):

def find(array, target)
  array.each_with_index do |element,index|
    return index if (element == target)  # return from find
  end
  nil  # If we didn't find the element, return nil
end

我希望能够突破一个障碍 - 有点像转发,并不是真的与循环有关。 实际上,我想要断开一个循环中的块而不终止循环。 要做到这一点,我做了一个单迭代循环:

for b in 1..2 do
    puts b
    begin
        puts 'want this to run'
        break
        puts 'but not this'
    end while false
    puts 'also want this to run'
end

希望这有助于下一个基于主题行的Google员工。


如果你想要你的块返回一个有用的值(例如,当使用#map#inject等), nextbreak也接受一个参数。

考虑以下:

def contrived_example(numbers)
  numbers.inject(0) do |count, x|
    if x % 3 == 0
      count + 2
    elsif x.odd?
      count + 1
    else 
      count
    end
  end
end

等同使用next

def contrived_example(numbers)
  numbers.inject(0) do |count, x|
    next count if x.even?
    next (count + 2) if x % 3 == 0
    count + 1
  end
end

当然,您可以始终将所需的逻辑提取到方法中,并从块内部调用该方法:

def contrived_example(numbers)
  numbers.inject(0) { |count, x| count + extracted_logic(x) }
end

def extracted_logic(x)
  return 0 if x.even?
  return 2 if x % 3 == 0
  1
end
链接地址: http://www.djcxy.com/p/95409.html

上一篇: How to break out from a ruby block?

下一篇: Difference between DateTime and Time in Ruby