以下示例显示,协议方法 pfoo
似乎没有直接链接。
$ clj -J-Dclojure.compiler.direct-linking=true
Clojure 1.10.1
user=> (defprotocol Foo (pfoo [this]))
Foo
user=> (defn libfn [x] (pfoo x))
#'user/libfn
user=> (extend-protocol Foo String (pfoo [_] :dude))
nil
user=> (libfn "hello")
:dude
user=> (alter-var-root #'user/pfoo (fn [old] (fn [this] (prn :this) (old this))))
#object[user$eval178$fn__179$fn__180 0x18eec010 "user$eval178$fn__179$fn__180@18eec010"]
user=> (libfn "hello")
:this
:dude
我提问的原因是,我正在尝试寻找一种通用的方法来修补协议方法以便在 sci + graal native-image 中工作。约束条件如下
- 在直接链接下工作(对于原生镜像的使用非常重要)
- 与第三方库一起使用
- 避免修改目标协议的源代码(不能添加 ^:dynamic, ^:redef 元数据)
我有一个解决方案可以在这里找到,但它依赖于编译时可以使用 alter-var-root 修改协议变量这一事实,即使是在直接链接的情况下。这是一个安全的假设吗?