一个口齿不清的问题在过去的几个月里,我一直在慢慢地学习lisp,在尝试从web浏览器获取输入和从REPL获取输入时遇到了一个问题。
具体问题是,在尝试计算此代码时:
假设sexp
是'(look north)
。(member (car sexp) '(look walk pickup drop))
从SBCL中的REPL来看,这工作正常,如预期的那样然而,当从hunchentoot抓取sexp
时,即使sexp
“看起来”与从REPL抓取的(car sexp)
相同,它似乎永远无法考虑'(look walk pickup drop)
的成员的结果。
我认为这可能是文件的字符编码,而不是从web浏览器抓取时的字符编码,但我不知道如何检验这个假设任何指点都非常感谢!
编辑
我接受输入的方式基于conrad barski的文本冒险游戏《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.)))
其中
sexp
是:(defparameter *allowed-commands* '(look walk pickup inventory))
我已经标记为冒犯正常工作的行,但是当
*allowed-commands*
来自作为请求的一部分从hunchentoot获取的请求参数时,string-to-read
看起来与我知道如何看待它相同,但在(car sexp)
中找不到。 最佳答案
你需要确定你得到的是什么它是一个符号吗Common Lisp具有TYPE-OF、INSPECT和descripe等函数来获取有关数据的更多信息。
* (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