假设我有以下两个文件:
;; 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
已“关闭”模块g
中定义的函数demo
。有没有办法解决这个问题?我真的想使用我在g
中重新定义的use-demo.scm
版本。
答案 0 :(得分:1)
好的,只是为了记录,我做了一些研究,并且发布了针对这个特定问题的解决方案,以防有人帮助。
诀窍是不在本地重新定义g
,而是将新函数“注入”demo
模块的名称到值的映射。
(add-to-load-path ".")
(use-modules (demo))
(module-define! (resolve-module '(demo)) 'g
(lambda (x) (+ x 1)))
(display (f 5))
(newline)
答案 1 :(得分:0)
如果您希望能够覆盖特定功能,则可以使用parameters对其进行配置。这有一些优点:
reload-module
将模块重新置于原始配置中。显然,主要的缺点是你需要为你想要覆盖的每个函数添加一些样板(虽然这就是卫生宏的用途,呵呵)。
以下代码可能有效。我还没跑过。
;; 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))
显然,如果您可以提供有关此功能的应用程序的其他信息,我可能会建议其他方法(还有其他一些方法)。