Evgenii Legotckoi
Evgenii LegotckoiТам. 26, 2016, 1:09 Т.Қ.

Пайдаланушы нұсқаулығы №24 - Ruby - Ерекшеліктерді өңдеу: құтқару

При выполнении программы могут возникать непредвиденные проблемы.  Файл, который нужно прочитать, может не существовать; диск может оказаться полным в момент записи данных; пользователь может некорректно ввести данные.

ruby> **file = open("some_file")**
**ERR: (eval):1:in `open': No such file or directory - some_file**

"Устойчивая" программа должна четко и изящно обработать такую ситуацию.  Предусмотреть подобное может быть мучительной, изматывающей задачей.  Предполагается, что программисты на С должны проверять результат каждого системного вызова, который потенциально может завершиться неудачей, и немедленно решить что должно быть сделано в этом случае:

FILE *file = fopen("some_file", "r");
if (file == NULL) {
  fprintf( stderr, "File doesn't exist.\n" );
  exit(1);
}
bytes_read = fread( buf, 1, bytes_desired, file );
if (bytes_read != bytes_desired ) {
  /* do more error handling here ... */
}
...

Это настолько утомительно, что у программиста может наблюдаться тенденция к росту небрежности; в результате чего программа не обрабатывает надежно исключения.  С другой стороны, правильное выполнение работы делает текст программы нецдобочитаемым, поскольку настолько громоздкая обработка ошибок замусоривает значащий код.

В Ruby, как в большинстве современных языков, мы обрабатываем исключения для блоков кода раздельно, таким образом работая эффективно с подобными сюрпризами и не перегружая напрасно программиста или того человека, который позднее будет читать этот код.  Блок кода, помеченный

begin
до тех пор, пока не происходит исключительная ситуация, которая передает управление блоку, отвечающему за ее обработку (начинается с
rescue
).  Если исключения не происходит, то
rescue
-блок не выполняется.  Следующий метод возвращает первую строку из текстового файла или
nil
, если происходит исключение:

def first_line( filename )
  begin
    file = open("some_file")
    info = file.gets
    file.close
    info  # Last thing evaluated is the return value
  rescue
    nil   # Can't read the file? then don't return a string
  end
end

Иногда бывает нужна возможность обойтись с проблемой творчески.  Здесь, если требуемый файл недоступен, мы пробуем использовать стандартный поток ввода:

begin
  file = open("some_file")
rescue
  file = STDIN
end

begin
  # ... process the input ...
rescue
  # ... and deal with any other exceptions here.
end

retry
может быть использован внутри
rescue
для запуска повторного выполнения блока с
begin
.  Теперь можно переписать предыдущий пример немного компактнее:

fname = "some_file"
begin
  file = open(fname)
  # ... process the input ...
rescue
  fname = "STDIN"
  retry
end

Тем не менее, здесь есть недостаток.  Несуществующий файл может заставить этот код выполняться снова и снова.  Вы должны остерегаться подобной западни при использовании

retry
для обработки исключительных ситуаций.

Любая библиотека Ruby возбуждает исключения при возникновении любой ошибки, и вы также можете явно возбуждать ошибки в своем коде.  Для этого используйте

raise
.  Этот оператор принимает один аргумент, который представляет из себя строку, описывающую исключение.  Аргумент не обязателен, но опускать его не стоит.  Его можно получить позже из специальной глобальной переменной
$!
.

ruby> **raise "test error"**
**test error**
ruby> **begin**
    |**raise "test2"**
    | **rescue**
    |**print "An error occurred: ",$!, "\n"**
    | **end**
An error occurred: test2
**nil**
Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
Ua

Qt - Тест 001. Сигналы и слоты

  • Нәтиже:84ұпай,
  • Бағалау ұпайлары4
Ua

Qt - Тест 001. Сигналы и слоты

  • Нәтиже:42ұпай,
  • Бағалау ұпайлары-8
ОК

Qt - Тест 001. Сигналы и слоты

  • Нәтиже:47ұпай,
  • Бағалау ұпайлары-6
Соңғы пікірлер
ИМ
Игорь МаксимовҚар. 22, 2024, 9:51 Т.Қ.
Django - Оқулық 017. Теңшелген Django кіру беті Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii LegotckoiҚаз. 31, 2024, 11:37 Т.Қ.
Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEҚаз. 19, 2024, 5:19 Т.Қ.
Qt Creator көмегімен fb3 файл оқу құралы Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовҚаз. 5, 2024, 4:51 Т.Қ.
Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5Шілде 5, 2024, 8:02 Т.Қ.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Енді форумда талқылаңыз
f
firstlunoxodАқп. 15, 2025, 1:46 Т.Қ.
Рисование на QGraphicsScene при зажатой кнопке мыши Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
Дмитрий
ДмитрийАқп. 3, 2025, 4:24 Т.Қ.
Создание deb-пакета. Как создать ярлык на рабочем столе после установки собственного deb-пакета? Всем привет. Сделал свой deb-пакет с программой. Всё устанавливается и работает. Ставлю по пути /usr/bin/my_application. Как для пользователя при установке пакета сразу создать ярлык на раб…
NW
Nayo WaiҚаң. 30, 2025, 7:22 Т.Қ.
не запускается компьютер!!! Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
n
nklyҚаң. 3, 2025, 12:52 Т.Қ.
Нужно запретить перемещение только некоторых итемов, остальные перемещать можно. Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
M
MarselТам. 17, 2023, 12:26 Т.Ж.
OAuth2.0 через VK, получение email Спасибо большое за помощь и простите за то что отнял время своей невнимательностью.

Бізді әлеуметтік желілерде бақылаңыз