Проблемы с вводом данных из Интернета с помощью hunchentoot и sbcl - PullRequest
1 голос
/ 18 июля 2011

Вопрос о шутке здесь. За последние пару месяцев я медленно изучал lisp и столкнулся с проблемой, когда пытался получить ввод из веб-браузера вместо получения ввода из REPL.

Конкретная проблема заключается в попытке оценить этот код:

Предположим, sexp равно '(look north).

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

Из REPL в SBCL это работает нормально и, как и ожидалось. Однако при извлечении sexp из hunchentoot, даже если sexp «выглядит» так же, как и из REPL, он никогда не сможет рассмотреть результат (car sexp) члена '(look walk pickup drop).

Я думаю, что это может быть символьная кодировка файла и кодировка символов sexp при получении из веб-браузера, но я не знаю, как проверить эту гипотезу. Любые указатели будут высоко оценены!

Редактировать

Способ ввода данных основан на текстовой приключенческой игре Конрада Барского «Земля Лиспа» и подробно описан ниже.

(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*.

Ответы [ 2 ]

4 голосов
/ 19 июля 2011

Вы должны убедиться, что ввод вы получаете.Это символ?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
1 голос
/ 18 июля 2011

Я никогда не использовал sbcl или Common Lisp, но это звучит как интернирующая проблема.Попробуйте вместо этого запрос:

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