Читаю http://www.haskell.org/haskellwiki/14_занимательных_эссе_о_языке_Haskell_и_функциональном_программировании Романа Душкина. В одно из глав приводится следующий код:
| Код | copyFile:: String -> String -> IO() copyFile src dst = do body <- readFile src writeFile dst body putStrLn ("Файл '" ++ src ++ "' скопирован в '" ++ dst ++ "'.")
main:: IO() main = do putStrLn "Пожалуйста, введите имя файла для копирования: " src <- getLine putStrLn "Введите новое имя файла: " dst <- getLine catch ( copyFile src dst ) (\e -> do putStrLn "Ошибка. Пожалуйста, повторите." main)
|
И дается комментарий к нему:
| Цитата | Рекурсивный вызов функции main не должен настораживать - это обычное дело. И опять же, имеется много возможностей для улучшения этой функции. Можно распознавать тип произошедшей ошибки и выводить на экран соответствующее сообщение. Можно не заставлять вводить пользователя оба имени снова, а просить вводить только то, с которым произошла ошибка. Можно придумать много чего еще. Все эти новые возможности опять оставляются для самостоятельной проработки.
Кроме того, вдумчивый читатель увидит здесь одну логическую ошибку, которая нарочито оставлена в целях обучения. Эта ошибка не приводит к генерации исключения, но может быть причиной непредсказуемого поведения программы. Кто первый из читателей сообщит о ней и о возможном способ ее преодоления автору, получит интересный подарок.
|
Что я только не пробовал - и /dev/zero в /dev/null копировал (казалось бы, должна кончится память - ан нет, ленивые вычисления) и /dev/random на раздел ограниченного размера, и пустой файл копировал, куда только можно. Разве что сигналы не посылал, но с ними поведение программы как раз вполне предсказуемо. Даже если мы попытаемся писать в unix-socket и внезапно закроем его - программа просто умрет из-за SIGPIPE. Ничего непредсказуемого.
Что скажите, господа? Я не могу найти логическую ошибку. А вы?
UPD: Да, фоновый процесс тоже успешно ждет, когда его реанимируют с помощью fg. |