2011-09-15 16 views
7

最近、Haskellにとって興味深いIDEのようなLeksah(Windows 7 64ビット版)0.10.0.4がインストールされました。しかし、私はそれを使用するときにプログラムへのユーザーの入力になると、何かを見落としています。readLnなどを使用するプログラムでLeksahデバッガを使用する

私は私のコードでは、非常に単純な

do 
    printStr "Prompt: " 
    x <- readLn 

ブロックを持っています。デバッガがreadLnにヒットすると、私はどこかで入力を提供できると期待します。しかし、私は入力ウィンドウを見つけることができません。最初はログウィンドウが有効になっていることが期待されていましたが、プログラムとやり取りする場所を見つけることができません。 GHCiで動くことはすべて期待どおりで、コードではないと確信しています。

さらに、「パッケージ - >実行」を実行すると、他のログ出力が到着するまで(再構築など)、プロンプトが表示されなくなります。

過去にLinux上でHaskellモードでEmacsを使用していたので、私はより使いやすい経験を望んでいたので、HaskellのトピックについていくつかのWindowsプログラマーを関与させることができました。何か不足していますか?

+0

+1 Windows 7 32ビット、GHC 7.0.3、Leksah 0.10.0.4では、この動作(またはむしろ非動作)を複製できます。 'getLine'などを待っているときは何も出力せず、次にファイルを変更するとプログラムが中断され、最終的に「プロンプト:」が表示されます。 –

答えて

4
このスレッドから

http://groups.google.com/group/leksah/browse_thread/thread/7d3e3bf64e56f190/30278795c23b2168

これは、我々はまだ対処されていない既知の問題です。 GCHiコマンドを標準に送信しますが、ユーザー入力を送信するための良い方法はありません。

私はこれをどのように修正するべきかわかりません。コマンドチャネルを使用してデバッグ中のプロセスにユーザー入力を送信することはできません(コードはコマンドを送信する前にghciからのプロンプトを待ちます)。

データを待つことなくstdinに送信するように設定すると、私たちが送信するGHCiコマンドを妨害する可能性があります(すべてが同じパイプを使用しているためです)。

GHCi自体のためのstdin/stdout/stderrパイプを別々にすることができるかどうかを調べる必要があります。プログラム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は、必要なimport文を追加する必要があります。あなたのパッケージの依存関係にプロセスやネットワークを追加する必要があります。)

これができるようになりますレクサがghciと話をするのが分かります。理想的には、stdoutとstderrをクリアしてこのソケットに書き込むこともできますが、Leksahは任意の出力にかなりうまく対処する必要があります。

+0

ありがとうございました...私は質問する前にかなりのグーグルをしましたが、コンテキストがgetChar()だったのでこれを逃しました。 Windows 7では、Telnetクライアントがデフォルトで読み込まれないというのは残念ですが、それは小さな問題です。 – Godeke

0

私はLeksahを使用していないので、あなたの質問のその部分に答えることはできませんが、Package -> Runを使用する際の問題はすぐに出力されるのではなく、バッファに保存されているためです。

デフォルトの出力バッファリングモードは実装によって定義されていますが、端末の場合は通常はラインバッファリングです。つまり、改行を追加するたびにバッフアが出力されますが、GHCiバッファリングは通常無効です。

ラインバッファリングモードでフラッシュをトリガするプロンプトの後に改行がないので、バッファリングを完全に無効にするにはhFlush stdout、またはhSetBuffering stdout NoBufferingにする必要があります。

詳細については、System.IO buffering operationsを参照してください。

2

同じ問題が発生しました。私は、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 

あなたは本当の関数(Leksahの外)でテストしたいときFAKE_INPUTをの#define行をコメントアウトすることができます。また、複数の入力に対して複数の定数を持たせることもできますが、最終的には最良の解決策となる単体テストに向かいます。

関連する問題