2011-09-15 25 views
7

Tôi vừa cài đặt Leksah (0.10.0.4 trên Windows 7 64 bit), có vẻ như là một IDE thú vị cho Haskell. Tuy nhiên, tôi rõ ràng nhìn thấy một cái gì đó khi nói đến người dùng đầu vào cho các chương trình khi sử dụng nó.Sử dụng trình gỡ rối Leksah với các chương trình sử dụng readLn và tương tự

Tôi có một rất đơn giản

do 
    printStr "Prompt: " 
    x <- readLn 

khối trong mã của tôi. Khi trình gỡ lỗi chạm vào readLn, tôi sẽ mong đợi để có thể cung cấp đầu vào ở đâu đó. Tuy nhiên, tôi không thể tìm thấy bất kỳ cửa sổ nhập liệu nào. Tôi dự kiến ​​ban đầu rằng cửa sổ nhật ký có thể được kích hoạt, nhưng tôi không thể tìm thấy bất cứ nơi nào để tương tác với chương trình. Chạy trong GHCi tất cả mọi thứ là như mong đợi, vì vậy tôi chắc chắn nó không phải là mã.

Hơn nữa, khi tôi chỉ thực hiện "Gói-> Chạy", lời nhắc sẽ không hiển thị cho đến khi một số đầu ra nhật ký khác đến (chẳng hạn như thực hiện xây dựng lại).

Đã sử dụng Emacs với chế độ Haskell trong quá khứ trên Linux, tôi đã hy vọng có thêm trải nghiệm thân thiện với người dùng để tôi có thể tham gia một số lập trình viên Windows trên các chủ đề Haskell. Tui bỏ lỡ điều gì vậy?

+0

+1 Tôi có thể sao chép hành vi này (hoặc đúng hơn là không hoạt động), Windows 7 32 bit, GHC 7.0.3, Leksah 0.10.0.4. Đầu ra không có gì khi chờ đợi một 'getLine' hoặc tương tự, sau đó khi tôi thay đổi tập tin nó sẽ làm gián đoạn chương trình, khiến nó cuối cùng in" Prompt: ". –

Trả lời

4

Từ chủ đề này http://groups.google.com/group/leksah/browse_thread/thread/7d3e3bf64e56f190/30278795c23b2168

Đây là một vấn đề được biết chúng tôi đã không được đề cập được nêu ra. Chúng tôi gửi các lệnh GCHi đến stdin của nó, nhưng chúng tôi không có cách nào tốt để gửi đầu vào của người dùng ở đó.

Tôi không chắc chắn cách khắc phục điều này. Chúng tôi không thể gửi đầu vào của người dùng đến quá trình đang được gỡ lỗi bằng cách sử dụng kênh lệnh của chúng tôi (mã của chúng tôi chờ lời nhắc từ ghci trước khi gửi lệnh).

Nếu chúng tôi thiết lập một cách nào đó để gửi dữ liệu đến stdin mà không cần đợi, nó có thể ảnh hưởng đến các lệnh GHCi mà chúng tôi gửi đi (vì nó vẫn đang đi xuống cùng một đường ống).

Chúng tôi cần tìm hiểu xem có cách nào chúng tôi có thể có các ống stdin/stdout/stderr riêng biệt cho chính GHCi và chương trình GHCi đang gỡ lỗi hay không.

Trong thời gian chờ đợi, bạn có thể yêu cầu ứng dụng mở một ổ cắm hoặc đặt tên là đường ống và ghi dữ liệu vào từ thiết bị đầu cuối khác. Một cái gì đó như thế này (không kiểm tra) ...

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 

(Bạn sẽ cần phải thêm quá trình và mạng để dependancies gói của bạn. Sau đó Ctrl + R nên thêm những điều khoản về nhập khẩu cần thiết.)

này sẽ cho phép tương tác, nhưng giữ stdin rõ ràng cho leksah để nói chuyện với ghci.Lý tưởng nhất là bạn sẽ giữ stdout và stderr rõ ràng quá và ghi vào ổ cắm này để thay thế, nhưng Leksah nên đối phó khá tốt với đầu ra tùy ý.

+0

Cảm ơn bạn vì điều đó ... Tôi đã làm khá nhiều Googling trước khi hỏi, nhưng bỏ lỡ điều này vì bối cảnh là getChar(). Đó là một sự xấu hổ rằng khách hàng telnet không được nạp theo mặc định trên Windows 7, nhưng đó là một điều nhỏ. – Godeke

0

Tôi không sử dụng Leksah, vì vậy tôi không thể trả lời một phần câu hỏi của bạn, tuy nhiên vấn đề của bạn khi sử dụng Package -> Run là do lời nhắc được lưu trong bộ đệm thay vì xuất ngay lập tức.

Chế độ đệm đầu ra mặc định được thực hiện xác định, nhưng đối với thiết bị đầu cuối nó thường đệm dòng, có nghĩa là bộ đệm được xả vào ouput bất cứ khi nào bạn thêm một dòng mới vào nó, trong khi đệm GHCi thường bị tắt.

Vì không có dòng mới sau dấu nhắc kích hoạt chế độ đệm trong dòng, bạn cần tự mình hFlush stdout hoặc hSetBuffering stdout NoBuffering để tắt hoàn toàn bộ đệm.

Để biết thêm chi tiết, hãy xem System.IO buffering operations.

2

Tôi đã gặp phải vấn đề tương tự và tôi đang xem xét sử dụng bộ tiền xử lý C để xác định nghĩa là tôi có muốn đầu vào giả để thử nghiệm hay không. Một cái gì đó dọc theo những dòng:

{-# 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 

Bạn có thể nhận xét ra dòng # định nghĩa FAKE_INPUT khi bạn muốn thử nghiệm với các chức năng thực tế (bên ngoài Leksah). Bạn cũng có thể có được ưa thích và có nhiều hằng số cho nhiều đầu vào nhưng bắt đầu đối với thử nghiệm đơn vị có thể là giải pháp tốt nhất cuối cùng.

Các vấn đề liên quan