【问题标题】:Guile/Scheme - redefine another module's internal functionGuile/Scheme - 重新定义另一个模块的内部功能
【发布时间】:2014-03-15 23:52:48
【问题描述】:

假设我有以下两个文件:

;; demo.scm
(define-module (demo)
  #:export (f))

(define (g x) 1)
(define (f x) (g x))

...在同一目录中:

;; use-demo.scm
(add-to-load-path ".")
(use-modules (demo))

(define (g x) (+ x 1))
(display (f 5))
(newline)

在 Guile (2) 中运行 use-demo.scm,我得到输出 1。所以看起来函数f 已经“关闭”了在模块demo 中定义的函数g。有没有办法解决这个问题?我真的很想使用我在use-demo.scm 中重新定义的g 的版本。

【问题讨论】:

    标签: scheme guile


    【解决方案1】:

    好的,为了记录,我做了一些研究,并发布了这个特定问题的解决方案,以防它对某人有所帮助。

    诀窍是在本地重新定义 g,而是将新函数“注入”到 demo 模块的名称到值的映射中。

    (add-to-load-path ".")
    (use-modules (demo))
    
    (module-define! (resolve-module '(demo)) 'g
      (lambda (x) (+ x 1)))
    
    (display (f 5))
    (newline)
    

    【讨论】:

      【解决方案2】:

      如果您希望能够覆盖特定的功能,您可以使用parameters 使它们可配置。这有一些优点:

      1. 您无需调用 reload-module 即可将模块恢复为原始配置。
      2. 更改仅适用于需要修改行为的代码范围。
      3. 使用多线程时可以正常工作。

      显然,主要的缺点是您需要为每个要允许被覆盖的函数添加一些样板文件(尽管这是卫生宏的用途,呵呵)。

      以下代码可能有效。我还没有运行它。

      ;; demo.scm
      
      (define-module (demo)
        #:export (f))
      
      (define (default-g x) 1)
      (define p (make-parameter default-g))
      (define (f x) ((p) x))
      
      
      ;; use-demo.scm
      (add-to-load-path ".")
      (use-modules (demo))
      
      (define (my-g x) (+ x 1))
      (parameterize ((@@ (demo) p) my-g)
        (display (f 5))
        (newline))
      

      显然,如果您可以提供一些关于此功能的应用程序的其他信息,我或许可以建议替代方法(还有其他一些方法)。

      【讨论】:

      • 谢谢彼得。我最终这样做了:github.com/yawaramin/ggspec/blob/…
      • 嗯。你的轻量级单元测试框架比我的少 (github.com/peter-b/geda-gaf/blob/master/libgeda/scheme/…)。 :-P 你可能想窃取我对assert-thrown 宏的想法。
      • 很明显,在“真实程序”中,如果有多个线程在运行,您的 stub 宏可能会很活泼,但它看起来是用于测试的绝佳解决方案!
      • 谢谢,我相信我的error? 宏中有类似的逻辑。我可能会扩展它来测试特定类型的错误。并且--同意,一旦您将多个线程混入其中,您就无法确定任何事情。
      猜你喜欢
      • 2018-12-19
      • 2014-08-29
      • 1970-01-01
      • 2011-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多