Использование отладчика Leksah с программами, использующими readLn и аналогичные

Недавно я установил Leksah (0.10.0.4 в 64-разрядной версии Windows 7), который кажется интересной IDE для Haskell. Тем не менее, я явно что-то упускаю из виду, когда речь заходит о пользовательском вводе программ при его использовании.

У меня очень просто

do
    printStr "Prompt: "
    x <- readLn

блок в моем коде. Когда отладчик нажимает на readLn, я ожидаю, что смогу где-нибудь предоставить ввод. Тем не менее, я не могу найти ни одного окна ввода. Сначала я ожидал, что окно журнала может быть включено, но я не могу найти где-нибудь взаимодействовать с программой. В GHCi все работает так, как ожидалось, поэтому я уверен, что это не код.

Кроме того, когда я просто выполняю "Package-> Run", приглашение не становится видимым до тех пор, пока не поступит какой-либо другой вывод журнала (такой как выполнение перестроения).

В прошлом я использовал Emacs с режимом Haskell для Linux, и я надеялся на более удобный для пользователя опыт, чтобы привлечь некоторых программистов Windows по темам Haskell. Я что-то упустил?

7 голосов | спросил Godeke 15 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 15 Sep 2011 06:21:42 +0400 2011, 06:21:42

3 ответа


0

Из этой темы http://groups.google.com/group/leksah/browse_thread/thread /7d3e3bf64e56f190 /30278795c23b2168

Это известная проблема, которую мы еще не рассмотрели. Мы посылаем команды GCHi на его стандартный ввод, но у нас нет и хорошего способа отправить туда пользовательский ввод.

Я не уверен, как мы должны это исправить. Мы не можем отправить пользовательский ввод в процесс, который отлаживается с помощью нашего командного канала (наш код ожидает приглашения от ghci перед отправкой команд).

Если мы настроим какой-либо способ отправки данных на стандартный ввод без ожидания, это может помешать отправляемым нами командам GHCi (потому что они все еще идут по одному каналу).

Нам нужно выяснить, есть ли какой-нибудь способ, которым мы можем иметь отдельные каналы stdin /stdout /stderr для самого GHCi, и программа GHCi отлаживается.

В то же время вы могли бы заставить ваше приложение открывать сокет или именованный канал и записывать входные данные с другого терминала. Примерно так (не проверено) ...

main = do 
    sock <- listenOn (PortNumber 8000) 
    -- Start a new terminal window (this command needs to be changed for OS X or Windows) 
    forkIO $ system "gnome-terminal -e \"telnet localhost 8000\"" 
    (handle, _, _) <- accept sock -- Wait for the new terminal to connect 
    -- You might want to add a call to hSetBuffering here 
    line <- hGetLine handle 
    print line 
    sClose sock

(Вам нужно будет добавить процесс и сеть в зависимости вашего пакета. Затем Ctrl + R должен добавить необходимые операторы импорта.)

Это позволит взаимодействовать, но оставьте stdin открытым для leksah, чтобы поговорить с ghci. В идеале вы должны держать stdout и stderr в чистоте и вместо этого писать в этот сокет, но Leksah должен довольно хорошо справляться с произвольным выводом.

ответил Hamish Mackenzie 15 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 15 Sep 2011 10:46:25 +0400 2011, 10:46:25
0

Я столкнулся с той же проблемой, и я рассматриваю возможность использования препроцессора C, чтобы буквально определить, хочу ли я вводить ложные данные для тестирования или нет. Что-то вроде этого:

{-# LANGUAGE CPP, TemplateHaskell #-}

module Main (
    main
) where

#define FAKE_INPUT

main :: IO ()
main = do
    putStrLn "Prompt: "
    x <- myReadLn
    putStrLn x

#ifdef FAKE_INPUT
myReadLn = return "fake string"
#else
myReadLn = readLn
#endif

Вы можете закомментировать строку, которая #defines FAKE_INPUT, когда вы хотите проверить с реальными функциями (за пределами Leksah). Вы также можете получить фантазию и иметь несколько констант для нескольких входов, но это начинается с модульного тестирования, которое может оказаться лучшим решением в конце.

ответил Billy 19 MaramTue, 19 Mar 2013 11:36:21 +04002013-03-19T11:36:21+04:0011 2013, 11:36:21
0

Я не использую Leksah, поэтому не могу ответить на эту часть вашего вопроса, однако ваша проблема при использовании Package -> Run вызвано тем, что приглашение хранится в буфере, а не выводится немедленно.

Режим буферизации вывода по умолчанию определяется реализацией, но для терминалов это обычно линейная буферизация, что означает, что буфер сбрасывается в выходной поток всякий раз, когда вы добавляете в него новую строку, тогда как в GHCi буферизация обычно отключена.

Поскольку после запроса нет строки для запуска сброса в режиме буферизации строки, вам нужно hFlush stdout самостоятельно или hSetBuffering stdout NoBuffering для полного отключения буферизации.

Подробнее см. в системе Буферные операции .IO .

ответил hammar 15 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowThu, 15 Sep 2011 08:55:50 +0400 2011, 08:55:50

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132