исключение Рубин
Исключения и исполнения всегда связаны между собой. Если вы открываете файл, который не существует, и не должным образом справиться с ситуацией, то ваша программа считается низкого качества.
Если происходит исключение, программа останавливается. Обработка исключений для всех типов ошибок, которые могут произойти во время выполнения программы, поэтому принять соответствующие меры, и не позволит программа полностью прекращена.
Рубин обеспечивает идеальный механизм обработки исключений. Мы можем прикрепить код , который может вызвать исключение, и использоватьспасательныепункты , чтобы сказать Руби идеальный тип исключения будет обрабатываться в блокеначала / конца.
грамматика
begin #开始 raise.. #抛出异常 rescue [ExceptionType = StandardException] #捕获指定类型的异常 缺省值是StandardException $! #表示异常信息 $@ #表示异常出现的代码位置 else #其余异常 .. ensure #不管有没有异常,进入该代码块 end #结束
Для того, чтобыначатьвсе отспасениязащищен. Если во время выполнения , за исключением кодового блока происходит, управление будет передано междуконцоми блокспасения.
Дляначатьблокировать друг условиеспасательную,Ruby и исключение брошено в свою очередь , к каждому сравнения параметров. Если условие спасательное исключение именовании и исключение типа брошенной тот же ток, или родительский класс, за исключением, матч был успешным.
Если исключение не соответствует ни одному из указанного типа ошибки, мы можем использовать условиеещепосле того, как все статьиспасения.
примеров
#!/usr/bin/ruby begin file = open("/unexistant_file") if file puts "File opened successfully" end rescue file = STDIN end print file, "==", STDIN, "\n"
Примеры вышеуказанного вывода работает. Как вы можетевидеть,STDIN заменитьфайл,так какоткрытне удалось.
#<IO:0xb7d16f84>==#<IO:0xb7d16f84>
Использованиеповторных попытокзаявление
Вы можете использоватьспасательныйблок , чтобы поймать исключение, а затем использовать блокповторных попытокзаявление начинаютначатьс самого начала.
грамматика
begin # 这段代码抛出的异常将被下面的 rescue 子句捕获 rescue # 这个块将捕获所有类型的异常 retry # 这将把控制移到 begin 的开头 end
примеров
#!/usr/bin/ruby begin file = open("/unexistant_file") if file puts "File opened successfully" end rescue fname = "existant_file" retry end
Ниже приводится схема процесса:
- Произошло исключение при открытии.
- Пропустить спасти. Fname быть переназначены.
- Переход к началу начать с повторной попытки.
- Файл успешно открыт.
- Продолжить основной процесс.
Примечание: Если переименованный файл не существует, это силы код неограниченное число попыток.Таким образом, обработка исключений, то соблюдайте осторожностьповторить попытку.
Используйтерейззаявление
Вы можете использовать операторрейзгенерирует исключение. Следующий метод генерирует исключение при вызове. Его второе сообщение будет выводиться.
грамматика
raise 或 raise "Error Message" 或 raise ExceptionType, "Error Message" 或 raise ExceptionType, "Error Message" condition
Первая форма просто повторно выбросить текущее исключение (если нет текущее исключение выбрасывается RuntimeError). Это используется для объяснения до входящего исключения исключение обработчика исключений.
Вторая форма создает новое исключениеRuntimeError,установив его сообщение в данной строке. После вызова стека, чтобы бросить исключение.
Третья форма первого параметра, чтобы создать исключение, а затем установить соответствующие сообщения в качестве второго параметра.
Четвертая форма и третья форма аналогична, вы можете добавить дополнительные условные операторы (например ,если)бросить исключение.
примеров
#!/usr/bin/ruby begin puts 'I am before the raise.' raise 'An error has occurred.' puts 'I am after the raise.' rescue puts 'I am rescued.' end puts 'I am after the begin block.'
Запуск в приведенном выше примере выход:
I am before the raise. I am rescued. I am after the begin block.
Еще одна демонстрацияRaiseПримеры использования:
#!/usr/bin/ruby begin raise 'A test exception.' rescue Exception => e puts e.message puts e.backtrace.inspect end
Запуск в приведенном выше примере выход:
A test exception. ["main.rb:4"]
Обеспечитьиспользование заявлений
Иногда, независимо от того, выбрасывается исключение, вам необходимо убедиться, что какой-то процесс завершается в конце блока кода. Например, вы можете открыть файл в момент записи, то при выходе из блока, вам необходимо убедиться, чтобы закрыть файл.
обеспечитьположение , чтобы сделать это. обеспечить помещается после последнего пункта спасательного и содержит блок кода завершения блока всегда выполняется. Это нормально , чтобы выйти из блока, бросать и обрабатывать исключения ли, будь то из - за непойманные исключения завершается, ни одно из этихотношений,не обеспечивают блок всегда будет работать.
грамматика
begin #.. 过程 #.. 抛出异常 rescue #.. 处理错误 ensure #.. 最后确保执行 #.. 这总是会执行 end
примеров
begin raise 'A test exception.' rescue Exception => e puts e.message puts e.backtrace.inspect ensure puts "Ensuring execution" end
Запуск в приведенном выше примере выход:
A test exception. ["main.rb:4"] Ensuring execution
Используялибо ещезаявления
Если предложениеещеприсутствует, то она, как правило , ставится после пунктаспасения,прежде чем любойобеспечить.
Телоещепредложение выполняется только тогда , когда тело кода без выбрасывания исключений.
грамматика
begin #.. 过程 #.. 抛出异常 rescue #.. 处理错误 else #.. 如果没有异常则执行 ensure #.. 最后确保执行 #.. 这总是会执行 end
примеров
begin # 抛出 'A test exception.' puts "I'm not raising exception" rescue Exception => e puts e.message puts e.backtrace.inspect else puts "Congratulations-- no errors!" ensure puts "Ensuring execution" end
Запуск в приведенном выше примере выход:
I'm not raising exception Congratulations-- no errors! Ensuring execution
Используйте $! Переменная может поймать брошенный сообщение об ошибке.
Ловить и бросать
поднять и спасительный механизм исключения может отказаться от исполнения при возникновении ошибки, иногда вам нужно прыгать в нормальном процессе некоторой глубоко вложенной структуры. На данный момент ловить и бросать, пригодится.
уловопределяет данное имя (может быть символом или String) метка в виде блока. Блок выполняется обычно знают, встречает бросок.
грамматика
throw :lablename #.. 这不会被执行 catch :lablename do #.. 在遇到一个 throw 后匹配将被执行的 catch end 或 throw :lablename condition #.. 这不会被执行 catch :lablename do #.. 在遇到一个 throw 后匹配将被执行的 catch end
примеров
В следующем примере, если пользователь введет '!' Ответить на любой запрос, используйте бросок, чтобы прекратить взаимодействие с пользователем.
def promptAndGet(prompt) print prompt res = readline.chomp throw :quitRequested if res == "!" return res end catch :quitRequested do name = promptAndGet("Name: ") age = promptAndGet("Age: ") sex = promptAndGet("Sex: ") # .. # 处理信息 end promptAndGet("Name:")
Вышеприведенная программа требует взаимодействия человека, вы можете попробовать на вашем компьютере. Запуск в приведенном выше примере выход:
Name: Ruby on Rails Age: 3 Sex: ! Name:Just Ruby
Исключение класса
стандартные классы и модули в Ruby выброшен. Все классы исключений образуют иерархию, в том числе и в верхней части внутреннего класса Exception. Следующий слой семь различных типов:
- Прерывание
- NoMemoryError
- SignalException
- ScriptError
- StandardError
- SystemExit
Фатальная является слой другого исключения, но интерпретатор Рубин только использовать его внутри страны.
ScriptError и StandardError есть некоторые подкатегории, но здесь нам нужно знать эти детали. Самое главное, чтобы создать наш собственный класс исключения, то они должны быть подкласс класса Exception или его потомства.
Давайте посмотрим на пример:
class FileSaveError < StandardError attr_reader :reason def initialize(reason) @reason = reason end end
Теперь посмотрим на следующем примере будет использоваться в вышеуказанных исключений:
File.open(path, "w") do |file| begin # 写出数据 ... rescue # 发生错误 raise FileSaveError.new($!) end end
Здесь самая важная линияподнятьFileSaveError.new ($!). Мы называем поднять схематично исключение произошло, он был принят новый экземпляр FileSaveError из-за специфических аномалий, вызванных данных при сбое записи.