1

ここで Lisp の質問です。私はここ数ヶ月ゆっくりと Lisp を学んでおり、Web ブラウザーから入力を取得しようとするときと、REPL から入力を取得しようとするときに問題に遭遇しました。

特定の問題は、このコードを評価しようとするときです。

であると仮定しsexpます'(look north)

(member (car sexp) '(look walk pickup drop))

SBCL の REPL から、これは正常に動作し、期待どおりに動作します。ただし、 hunchentoot から を取得すると、REPL と同じように「見える」sexpにもかかわらず、 のメンバーの結果を考慮することができないようです。sexp(car sexp)'(look walk pickup drop)

ファイルの文字エンコーディングとsexp、Web ブラウザから取得したときの文字エンコーディングの違いだと思いますが、この仮説を検証する方法がわかりません。どんなポインタでも大歓迎です!

編集

私が入力を取り込む方法は、Conrad Barski による「Land of Lisp」のテキスト アドベンチャー ゲームに基づいており、以下で詳しく説明します。

(defun game-read (string-to-read)
  (let ((cmd (read-from-string
               (concatenate 'string "(" string-to-read ")"))))
    (describe cmd)
    (flet ((quote-it (x)
                     (list 'quote x)))
      (cons (car cmd) (mapcar #'quote-it (cdr cmd))))))

これは次のようにラップされます。

(defun game-eval (sexp)
  (if (member (car sexp) *allowed-commands*) ;Offending line                                                                          
      (eval sexp)
      '(i do not know that command.)))

どこに*allowed-commands*ある:

(defparameter *allowed-commands* '(look walk pickup inventory))

通常は問題なく動作する行に問題があるとラベル付けした行ですがstring-to-read、リクエストの一部として hunchentoot からフェッチされたリクエストパラメータからのものである場合、どのように見ても同じように見えますが(car sexp) *allowed-commands* .

4

2 に答える 2

4

入力が何であるかを確認する必要があります。シンボルですか?Common Lisp には、TYPE-OF、INSPECT、DESCRIBE などの関数があり、データに関する詳細情報を取得できます。

* (describe 'north)

COMMON-LISP-USER::NORTH
  [symbol]


* (type-of 'north)

SYMBOL

次の質問は、それがシンボルである場合、どのパッケージに含まれているかです。

* (symbol-package 'north)

#<PACKAGE "COMMON-LISP-USER">

他のシンボルは同じパッケージに含まれていますか?

次の質問は、それがシンボルまたは文字列の場合、大文字はどうするかということです。

* (symbol-name 'north)

"NORTH"

デフォルトでは、記号は大文字です。入力から読み取られたシンボルの場合は、そうである必要はありません。

MEMBER を使用して、純粋な文字列の比較を行うこともできます。

* (member (symbol-name '|Foo|)
          '(foo bar baz)
          :key #'symbol-name :test #'equalp)

(FOO BAR BAZ)   ; this is the usual return value,
                ; the rest list with first item found
于 2011-07-18T20:08:16.377 に答える
1

私は sbcl や Common Lisp を使ったことはありませんが、これはインターンの問題のように思えます。代わりに次のクエリを試してください。

(member (intern (car sexp)) '(look walk pickup drop)))
于 2011-07-18T19:59:19.107 に答える