【问题标题】:Using parenscript set-interval function使用 parenscript 设置间隔函数
【发布时间】:2017-12-29 11:35:24
【问题描述】:

我见过很多例子,其中 (set-interval "my-method" n) 函数用于在浏览器中每 n 秒调用一次函数,但我无法运行 set-interval 函数。

如果我使用:

(ql:quickload :parenscript)
(use-package :parenscript)
(use-package: ps-window-wd-symbols)

我遇到很多命名空间冲突,@​​987654324@ 仍然是一个未定义的函数。

我也尝试过(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”。

【问题讨论】:

  • 如果这些示例在您可以编译和运行的代码中,也许您可​​以使用 slime 来查找符号的定义 (M-.),这将为您提供关于它在哪里的线索。您是否尝试过使用(apropos "SET-INTERVAL")?我是否正确理解您正在尝试查找导出此符号的包?
  • 另外你确定(set-interval a b) 通常没有a 是一个函数(不是一个字符串)和b 毫秒数,或者我在api上不清楚
  • Apropos 告诉我它是由 Smackjack 和 ~ps-windows-wd-symbols~ 提供的。我将尝试重新混淆 ~ps-windows-wd-symbols~ 并具体指定 smackjack。
  • 我已经更新了主要问题。
  • 您在第二个 use-package 表单中放错了 :。我想这是一个错字。

标签: lisp common-lisp parenscript


【解决方案1】:

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-intervalps-window-wd-symbols:set-interval 都映射到同一个 Javascript 函数。

【讨论】:

    【解决方案2】:

    使用此函数的最佳方法是在 de defmacro ps 中使用它。

    如代码中的 doc cmets 所示,您可以找到以下内容:

    ;;这些是导出 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 形式(一个隐含的 progn),将这些形式编译为 宏扩展时的 JavaScript 字符串。展开成这样的形式 计算结果为字符串。

    看看the following gist

        (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))))))))
    

    【讨论】:

    • 您的好。我希望这对你有帮助
    猜你喜欢
    • 2018-06-26
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 2016-07-25
    • 1970-01-01
    • 2022-10-23
    • 2014-10-05
    • 2011-11-12
    相关资源
    最近更新 更多