我见过很多例子,其中(set-interval "my-method" n)
函数用于在浏览器中每n秒调用一次函数,但是我无法运行set-interval
函数。
如果我使用:
(ql:quickload :parenscript)
(use-package :parenscript)
(use-package: ps-window-wd-symbols)
我遇到了很多命名空间冲突,而set-interval
仍然是一个未定义的函数。
我也尝试了(ps:unobfuscate-package "ps-window-wd-symbols")
,它返回NIL并且什么也没做。
这样做的正确方法是什么?
更新:使用(apropos "set-interval")
提供:
(apropos "set-interval")
SET-INTERVAL
SMACKJACK::SET-INTERVAL
PS-WINDOW-WD-SYMBOLS:SET-INTERVAL
所以它在两个地方提供。尝试(smackjack::set-interval NIL NIL)
也会导致未定义的函数错误。
使用M-.
在我的主项目命名空间中返回“No known Symbol”。
答案 0 :(得分:3)
使用此功能的最佳方法是在de defmacro ps中使用它。
如代码中的doc注释所示,您可以找到:
;;这些是导出JS和浏览器DOM的便利包;; 符号。如果你:在包FOO中使用包,然后;; 混淆FOO,它会阻止JS符号的获取;;错位。
;;对于大多数Web开发任务,您要导入PS-JS-SYMBOLS, ;; PS-WINDOW-WD-SYMBOLS(包括DOM级别2和w3c窗口 ;;工作草案),可能还有PS-DOM-NONSTANDARD-SYMBOLS。
并且set-interval函数由ps-window-wd-symbols包导出而不是parenscript包
defmacro ps:
"给定Parenscript表单(隐含的预测),将这些表单编译为 宏扩展时的JavaScript字符串。扩展为一种形式 评估为字符串。
(ql:quickload :parenscript)
(ql:quickload :cl-who)
(ql:quickload :clack)
(in-package :ps)
(defvar *canvas-id* "alien-canvas")
(clack:clackup
(lambda (env)
(list 200
'(:content-type "text/html")
(list
(who:with-html-output-to-string (*standard-output* nil :prologue t :indent t)
(:html
(:head
(:script :type "text/javascript"
(who:fmt "~A"
(ps (defvar x 0)
(defvar y 0)
(defvar dx 1)
(defvar dy 1)
(defvar img (new -image))
(setf (@ img src) "http://www.lisperati.com/lisplogo_alien_128.png")
(set-interval "draw()" 5)
(defun draw ()
(let ((w 128)
(h 75)
(canvas ((@ document get-element-by-id) #.*canvas-id*)))
(if (or (not canvas) (not (@ canvas get-context)))
(return false))
(let ((ctx ((@ canvas get-context) "2d")))
((@ ctx fill-rect) 0 0 500 500)
(if (and (<= (+ x dx w) 500) (<= 0 (+ x dx)))
(setf x (+ x dx))
(setf dx (* dx -1)))
(if (and (<= (+ y dy h) 500) (<= 0 (+ y dy)))
(setf y (+ y dy))
(setf dy (* dy -1)))
((@ ctx draw-image) img x y))))))))
(:body (:canvas :id *canvas-id* :width 500 :height 500))))))))
答案 1 :(得分:0)
AFAIK,set-interval
只是一个符号,而不是一个实际的函数(在Lisp中)。 Parenscript生成Javascript代码,然后可以在JS解释器(例如浏览器)中运行,但这不是解释器本身。
Parenscript提供了一种模糊符号的方法,但也可以保证某些符号不会被混淆。 The documentation说:
因为Parenscript对DOM或其他内容一无所知 JavaScript库,库函数和属性名称可能是 无意中混淆了。为了帮助防止这种情况,Parenscript自带了 ps-dom1-symbols,ps-dom2-symbols,ps-window-wd-symbols, ps-dom-nonstandard-symbols和ps-dhtml-symbols符号包 将各种DOM属性和函数标识符定义为导出 符号(在区分大小写和不区分大小写的变体中),你 可以导入到您的包中以帮助防止像pageXOffset这样的符号 从被混淆。 ps-dhtml-symbols包中包含 最广泛的符号,最常用。
如果使用模糊处理和外部JavaScript库,则可以使用 使用符号来定义自己的包的相同技术 不要混淆。
Smackjack还会调用setInterval
(pusher.lisp:189),但不会导入上述包中的符号。这不是一个真正的问题,因为这里只使用了符号的名称,并且没有进行模糊处理。换句话说,smackjack::set-interval
和ps-window-wd-symbols:set-interval
都映射到相同的Javascript函数。