2012-08-21 2 views
1

Мне интересно вырваться из внешнего и внутреннего блоков, если исключение выбрасывается во внутренний блок ruby. Код может выглядеть примерно так:Вырыв из рубинового внутреннего блока с использованием catch/throw

catch "ExitBlock" do 
     foo.each_with_index do |el, idx| 
     bar = ... // do more stuff, 
     bar.each_with_index do |el1, idx1| 
      if some_bad_stuff 
      throw "ExitBlock" 
      end 
     end 
     end 
    end 

если some_bad_stuff верно, то следует выйти как наружный блок и внутренний блок, а не только внутренний блок. приведенный выше код дает мне ArgumentError однако с:

ArgumentError: uncaught throw "ExitBlock"

Что я делаю неправильно?

ответ

2

Он работает с символами:

catch :exit_block do 
    foo.each_with_index do |el, idx| 
    bar = ... // do more stuff, 
    bar.each_with_index do |el1, idx1| 
     if some_bad_stuff 
     throw :exit_block 
     end 
    end 
    end 
end 

Но документация говорит "[argument] can be an arbitrary object, not only Symbol"

Я понятия не имею, что происходит.

+0

согласился! Я использовал струны, и это сломало бы меня. Я должен посмотреть на источник. с символами он работает отлично. – randombits

+1

Какую версию Ruby вы используете? 'throw'ing и' catch'ing произвольные объекты были добавлены только в 1.9.0, перед этим вы могли бы просто «бросать» и «улавливать» 'Символ'. –

+0

Я использую ruby ​​1.9.3p125 – megas

0

Было бы намного чище, чтобы просто выйти из цикла, а не приносить исключения в смеси:

foo.each_with_index do |el, idx| 
    bar = ... // do more stuff, 
    break_outer = false 
    bar.each_with_index do |el1, idx1| 
     if some_bad_stuff 
      break_outer = true 
      break 
     end 
    end 
    if break_outer 
     break 
    end 
end 
+1

Это плохо. Он вырвется из внутреннего блока. Если вы читаете оригинальное сообщение, в нем конкретно упоминается, что требование состоит в том, чтобы вырваться из обоих блоков. – randombits

+0

Извините, я пропустил внутренний цикл. Закрепление. – pizen

+0

Спасибо. Я удалил голосование за ваше редактирование. Я все еще думаю, что решение catch/throw чище, чем добавление этого дополнительного состояния. Кроме того, если вам нужно еще больше гнездиться, это будет труднее следовать и поддерживать. – randombits

Смежные вопросы