対話型REPL IO関数は何ですか? -- io フィールド と common-lisp フィールド と read-eval-print-loop フィールド 関連 問題

what is the interactive REPL IO function?












1
vote

問題

日本語

私はしばらくの間共通のLispを学んでいます、私が満たした質問がありました ユーザー入力出口までユーザーがいくつかの単語を入力できるような機能を実装できる方法。 (実際には、どのような種類のコマンドライン対話型機能APIがそのような要件に合わせても知りたい)

e.g。 REPLで「Wordを入力してください:」を求めてから、ユーザー入力をGlobal My-Words に保存し、ユーザー入力が "EXIT"のときに終了します。

英語

I have been learning Common Lisp for a while, there was a question I have met that how I can implement such a function which allows user to input some words until user input exit. (actually I want to know what kind of command line interactive function APIs fit such requirement)

e.g. prompt "please input a word: " in the REPL, then store user inputs into a global my-words , exit when user input "exit".

</div
        
     
     

回答リスト

5
 
vote

仕様は少し不完全です(例えば、問題のある単語を構成するのですか。ユーザーが複数の単語を追加した場合はどうなりますか。入力が空の場合はどうなりますか?)以下では、 CL-PPCRE を使用して、入力をさまざまな単語に分割して一度に追加します。一般的に役に立つようです。あなたのケースでは、より多くのエラーチェックを追加したい場合があります。

ユーザーと対話したい場合は、 jetty.http.port=80801 ストリーム。ここで、あなたが要求したように、グローバルな変数を持つバージョンを提示します(入出力とは別に)副作用なしの別のものだけでなく、(入出力とは別に)。

グローバル変数

グローバル変数を定義し、空の調整可能な配列でそれを初期化します。 最後に単語を追加することが簡単なので、アレイを使用していますが、キューも使用できます。

 <コード> jetty.http.port=80802  

次の関数はグローバル変数を変化させる:

 <コード> jetty.http.port=80803  
  • <コード> jetty.http.port=80804 式と loop> -Specificキーワードのみがある単純な構文を使用します。最初に jetty.http.port=80805 にプロンプ​​トを書きます。 jetty.http.port=80806 <コード> jetty.http.port=80807 ディレクティブは、 <コード> jetty.http.port=80808 。レイナーがコメントで指摘したように、私たちは <コード> jetty.http.port=80809 ユーザが返信することが予想される前にメッセージが効果的に印刷されるようにする。

  • それでは、同じ双方向ストリームから全行を読み、それを単語のリストに分割します.Wordは空白以外の文字の文字列です。

  • <コード> Listの上に繰り返し、 <コード> jetty.http.port=70701 < /コード> 。しかし、In Encouter 998876622 とすぐに、ループを終了します。 <コード> jetty.http.port=70703 <コード> 、テスト大文字と小文字が区別されます。

副作用自由アプローチ

上記のようにグローバル変数を持つ

は推奨されます。 が単語のリストを返すプロンプトを持っているだけでよい場合にのみ、次のものが十分になります。ここでは、 <コード> / < href = "http://www.lispworks.com/reference/hyperspec/body/f_revers.htm" rel = "nofollow"> <コード> jetty.http.port=70705 結果の単語のリストを作成する。

 <コード> jetty.http.port=70706  

単語について

JKiiskiがコメントしているので、 jetty.http.port=70707 で単語を分割するのが良いかもしれません。 私はさまざまな組み合わせを試してみましたが、次の結果は奇妙な例の文字列に満足しているようです:

<プレクラス= "LANG-LISP Prettyprint-Override"> <コード> jetty.http.port=70708

最初にすべての空白を取り除き、文字列を文字列のリストに分割します。これにより、句読点を含めることができます。 それから、EAC 文字列は jetty.http.port=70709 でそれ自体が分割され、 <コード > Package: * Pin: release a=testing Pin-Priority: 100 0 別々の単語のリストを形成する。 しかし、私はあなたの実際のニーズが何であるかは本当に推測できないので、あなたはおそらくあなた自身の 998877631 関数を検証して分割する必要があります。

 

You specification is a little bit incomplete (e.g. what constitutes a word in your problem? What if the user add multiple words? What if the input is empty?). Here below I am using CL-PPCRE to split the input into different words and add them all at once, because it seems useful in general. In your case you might want to add more error checking.

If you want to interact with the user, you should read and write from and to the *QUERY-IO* stream. Here I'll present a version with a global variables, as you requested, as well as another one without side-effects (apart from input/output).

With a global variable

Define the global variable and initialize it with an empty adjustable array. I am using an array so that it is easy to add words at the end, but you could also use a queue.

(defvar *my-words* (make-array 10 :fill-pointer 0 :adjustable t)) 

The following function mutates the global variable:

(defun side-effect-word-repl ()   (loop      (format *query-io* "~&Please input a word: ")      (finish-output *query-io*)      (let ((words (ppcre:split                    '(:greedy-repetition 1 nil :whitespace-char-class)                    (read-line *query-io*))))        (dolist (w words)          (when (string-equal w "exit") ; ignore case            (return-from side-effect-word-repl))          (vector-push-extend w *my-words*))))) 
  • The LOOP uses the simple syntax where there are only expressions and no loop-specific keywords. I first write the prompt to *QUERY-IO*. The ~& FORMAT directive performs the same operation as FRESH-LINE. As Rainer pointed out in comments, we have to call FINISH-OUTPUT to ensure the message is effectively printed before the user is expected to reply.

  • Then, I read a whole line from the same bidirectional stream, and split it into a list of words, where a word is a string of non-whitespace characters.

  • With DOLIST, I iterate over the list and add words into the global array with VECTOR-PUSH-EXTEND. But as soon as I encouter "exit", I terminate the loop; since I rely on STRING-EQUAL, the test is done case-insensitively.

Side-effect free approach

Having a global variable as done above is discouraged. If you only need to have a prompt which returns a list of words, then the following will be enough. Here, I use the PUSH/NREVERSE idiom to built the resulting list of words.

(defun pure-word-repl ()   (let ((result '()))     (loop        (format *query-io* "~&Please input a word: ")        (finish-output *query-io*)        (let ((words (ppcre:split                      '(:greedy-repetition 1 nil :whitespace-char-class)                      (read-line *query-io*))))          (dolist (w words)            (when (string-equal w "exit")              (return-from pure-word-repl (nreverse result)))            (push w result)))))) 

Note about words

As jkiiski commented, it might be better to split words at :word-boundary. I tried different combinations and the following result seems satisfying with weird example strings:

(mapcan (lambda (string)            (ppcre:split :word-boundary string))    (ppcre:split     '(:greedy-repetition 1 nil :whitespace-char-class)   "amzldk           'amlzkd d;:azdl azdlk"))  =>  ("amzldk" "'" "amlzkd" "d" ";:" "azdl" "azdlk") 

I first remove all whitespaces and split the string into a list of strings, which can contain punctuation marks. Then, each string is itself splitted at :word-boundary, and concatenated with MAPCAN to form a list of separate words. However, I can't really guess what your actual needs are, so you should probably define your own SPLIT-INTO-WORDS function to validate and split an input string.

</div
 
 
       
       
2
 
vote
vote
ベストアンサー
 
<事前> <コード> CL-USER 23 > (progn (format t "~%enter a list of words:~%") (finish-output) (setf my-words (read)) (terpri)) enter a list of words: (foo bar baz)

または

<事前> <コード> jetty.http.port=80800
 
CL-USER 23 > (progn                (format t "~%enter a list of words:~%")                (finish-output)                (setf my-words (read))                (terpri))  enter a list of words: (foo bar baz) 

or

CL-USER 28 > (loop with word = nil                     do                    (format t "~%enter a word or exit:~%")                    (finish-output)                     (setf word (read))                    (terpri)                     until (eql word 'exit)                     collect word)  enter a word or exit: foo   enter a word or exit: bar   enter a word or exit: baz   enter a word or exit: exit  (FOO BAR BAZ) 
</div
 
 
 
 

関連する質問

2  NORESOURCEENTRY-X Repl Tree Pounts  ( Noresourceentry x repl tree output ) 
要素がIDを持つことを確実に確実に確実にしているXamarinテストアプリの何らかの理由で、 "NOROREURCEENTRY"を見ることしかできません。 理由はないのですが、それはエミュレータ、ターゲットフレームワーク、または他のものに関連しています。 ...

12  非同期出力をうまく処理するPython Relpを実装する方法  ( How to implement a python repl that nicely handles asynchronous output ) 
私は、単純なread-eval-print-loopでいくつかのコマンドを受け入れることができるPythonベースのアプリを持っています。入力を取得するには、 raw_input('> ') を使用しています。 UNIXベースのシステムでは、物事をほとんど良く...

18  Pythonのインタプリタでは、 "'"なしで戻る  ( In python interpreter return without ) 
Pythonでは、次のような変数をどのように返しますか。 <事前> <コード> function(x): return x 'x' の周囲の ' )がなくても( x ) ...

2  最大Leiningen Repl historyのカウントを設定する方法  ( How to set the maximum leiningen repl history count ) 
LEIN REPLのコマンド履歴は、500コマンドでトップアウトしています。この数を増やすか、無制限に設定する方法はありますか? ...

0  HTTPサーバーへのNet.ConnectのEpipe  ( Epipe on net connect to an http server ) 
RoderのNet.Connectを使用してノードHTTP Server Socket(ExpressJS)に接続して、そのソケットを私のHTTPサーバーと起動コマンドに接続できるようにするためにそのソケットを私のRelpに渡してください。 これを試してみる...

1  Rubyのためのインタラクティブコンソールのようなアイドル  ( Idle like interactive console for ruby ) 
私はRubyで始まり、Pythonのアイドルに似たインタラクティブなコンソールがあるかどうか、あなたはコンテキストの強調表示と自動補完を使って知っています。私はIRBを試してみましたが、それはかなりスパルタです(それは仕事をしましたが、それについての質問はあり...

3  EMACSのエラーが答えを開始しました  ( Errors in emacs starting repl ) 
Clojure開発にEMACSを使用しています。 Cider-Jack-inでRelpを起動したとき、私はいくつかのエラーが発生しましたが、私はエコーエリアの最後の行だけを見ることができます。エコーエリアをクリックすると、「ミニバッファウィンドウがアクティブ...

4  Julia:RelpまたはCommand Lineから実行するかどうかを調べる  ( Julia find out if run from repl or command line ) 
Juliaスクリプト<コード> OU=RoleGroups,OU=MOR,OU=rEU,DC=ah1,DC=ad,DC=megacorp,DC=com7 がコマンドラインから呼び出されたかどうかを判断する方法は、<コード> 998877766618 、または...

1  いくつかの言語のread-eval-printループ(repl)  ( Read eval print loop repl for several languages ) 
私はいくつかの推奨されているのか疑問に思っていた<a href="http://en.wikipedia.org/wiki/read-eval-print_loop" rel= eval-print_loop" rel="nofollout_> read-ev...

2  予期しない動作を迅速に返信します  ( Swift repl unexpected behaviour ) 
SWIFT REPLで次のコードを使用している場合は、予期しない結果が得られます。 <事前> <コード> 1> func addA(s: String)->String { 2. return s + "a" 3. } 4. ...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有