1

假设我有以下两个文件:

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

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

4

2 回答 2

3

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

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

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

(module-define! (resolve-module '(demo)) 'g
  (lambda (x) (+ x 1)))

(display (f 5))
(newline)
于 2014-02-16T22:00:54.613 回答
0

如果您希望能够覆盖特定的功能,您可以使用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))

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

于 2014-02-26T13:38:22.723 回答