下面是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中放任何特定的东西。


当前回答

我只是想能够跳出一个块——有点像一个向前的后向,并不是真正的循环。实际上,我想在不终止循环的情况下中断一个循环中的块。为了做到这一点,我让块一个迭代循环:

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

希望这有助于下一个谷歌登陆这里基于主题行。

其他回答

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

当在块中使用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 == "quit\n"  # If this break statement is executed...
  puts eval(line)
end
puts "Good bye"              # ...then control is transferred here

最后,return在block中的用法:

Return总是导致封闭方法返回,不管它在块内嵌套有多深(lambdas除外):

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

在这个简化的例子中,Next和break似乎做了正确的事情!

class Bar
  def self.do_things
      Foo.some_method(1..10) do |x|
            next if x == 2
            break if x == 9
            print "#{x} "
      end
  end
end

class Foo
    def self.some_method(targets, &block)
      targets.each do |target|
        begin
          r = yield(target)
        rescue  => x
          puts "rescue #{x}"
        end
     end
   end
end

Bar.do_things

输出:1 3 4 5 6 7 8

我只是想能够跳出一个块——有点像一个向前的后向,并不是真正的循环。实际上,我想在不终止循环的情况下中断一个循环中的块。为了做到这一点,我让块一个迭代循环:

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

希望这有助于下一个谷歌登陆这里基于主题行。

你有四种方法以“非异常”方式展开堆栈:next、break、return和throw。

Next将导致块返回。

Break将导致yield给该块的方法返回。

Return将导致定义该块的方法返回。

Throw将遍历堆栈,直到找到具有匹配符号的catch,并使其返回。这很像非异常情况的“轻量级”异常。

它们都可以接受一个返回值,这个返回值将由它们所导致的返回值返回,而不是它们上一个表达式通常返回的值。

下面是一些例子:

def doSomething
  puts "> doSomething"
  yield
  puts "< doSomething"
end

def withNext
  puts "> withNext"
  doSomething do
    puts "> block"
    puts "* NEXT! causes the block to return to doSomething"
    next
    puts "< block"
  end
  puts "< withNext"
end

def withBreak
  puts "> withBreak"
  doSomething do
    puts "> block"
    puts "* BREAK! causes doSomething to return to withBreak"
    break
    puts "< block"
  end
  puts "< withBreak"
end

def withReturn
  puts "> withReturn"
  doSomething do
    puts "> block"
    puts "* RETURN! causes withReturn to return"
    return
    puts "< block"
  end
  puts "< withReturn"
end

def withThrow
  puts "> withThrow"
  catch :label do
    puts "> catch :label"
    doSomething do
      puts "> block 1"
      doSomething do
        puts "> block 2"
        puts "* THROW! causes catch :label to return to withThrow"
        throw :label
        puts "< block 2"
      end
      puts "< block 1"
    end
    puts "< catch :label"
  end
  puts "< withThrow"
end

withNext
puts "* Done"
puts
withBreak
puts "* Done"
puts
withReturn
puts "* Done"
puts
withThrow
puts "* Done"

输出:

> withNext
> doSomething
> block
* NEXT! causes the block to return to doSomething
< doSomething
< withNext
* Done

> withBreak
> doSomething
> block
* BREAK! causes doSomething to return to withBreak
< withBreak
* Done

> withReturn
> doSomething
> block
* RETURN! causes withReturn to return
* Done

> withThrow
> catch :label
> doSomething
> block 1
> doSomething
> block 2
* THROW! causes catch :label to return to withThrow
< withThrow
* Done

使用关键字break而不是return