Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Очень хитрая логическая ошибка 
V
    Опции темы
afiskon
Дата 20.6.2011, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 31.3.2011
Где: Россия, Москва

Репутация: нет
Всего: 4



Читаю 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.

Это сообщение отредактировал(а) afiskon - 20.6.2011, 11:27
PM MAIL WWW   Вверх
calabiyau
Дата 21.6.2011, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 16.11.2010

Репутация: нет
Всего: нет



Цитата(afiskon @  20.6.2011,  11:20 Найти цитируемый пост)
Что скажите, господа? Я не могу найти логическую ошибку. А вы?

хэндл открытого на чтение файла будет висеть если writeFile dst body кинет исключение (пока не отработает сборщик мусора). А значит, если на энной итерации мы обратимся к нему на запись, успешность операции будет зависеть от того, прошелся ли гц, али нет. 
Код

catch ( copyFile src dst ) (\e -> do
    putStrLn "Ошибка. Пожалуйста, повторите."
    performGC
    main)


или:
Код

copyFile src dst = bracket (openFile src ReadMode) hClose (hGetContents >=> writeFile dst)


Это сообщение отредактировал(а) calabiyau - 21.6.2011, 15:12
PM MAIL   Вверх
afiskon
Дата 21.6.2011, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 31.3.2011
Где: Россия, Москва

Репутация: нет
Всего: 4



С ума сойти smile Спасибо!
PM MAIL WWW   Вверх
ruberoid
Дата 15.9.2011, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 29
Регистрация: 2.9.2011

Репутация: нет
Всего: нет



Я бы тоже сам не разобрался. Так всё запутанно. smile 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума «Функциональные языки: общие вопросы»
Void
  • Пожалуйста, создавайте темы с содержательными названиями. Если у Вас вопрос по конкретному языку, укажите его в заголовке, например: «[Haskell] Как использовать монаду State».
  • Уважаемые учащиеся, здесь всегда рады помочь Вам, но не делать за Вас вашу работу. У вас гораздо больше шансов получить помощь, если Вы приложите усилия и поделитесь с нами проблемами и результатами. В противном случае добро пожаловать в раздел Центр Помощи.
  • Получив ответ на интересующий Вас вопрос, не забудьте пометить его как решённый.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Void.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Функциональные языки: общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0464 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.