Julia-lang:从已安装的模块扩展方法,“使用”订单

时间:2017-01-30 11:56:38

标签: module julia

我正在尝试从JSON.jl模块扩展一个方法,特别是我这样做(扩展'JSON.lower',如文档所示,允许序列化), 一般来说 - 我问的是当前Julia“最佳实践”是什么,用于从另一个模块扩展方法 - 特别是 - 如果这是一个方法来改变模块的某些策略(如本例中{{1 }})。

实际上有一种方法可以保证导入的模块将使用更新的方法,除了修补它吗?

让我们展示期望和险恶的行为:

JSON.jl
  • 如果在运行之前的任何地方 - 某段代码已经运行了这个方法, module TestProgram using JSON import JSON.lower # not sure whether this is needed JSON.print(Set([1,2,1])) ## output: ## {"dict":{"2":null,"1":null}} ## not the output I want or expect ## in this case might be a good idea to patch JSON.jl and pull request ## and "JSON.print" - is now compiled with this default behaviour JSON.lower{T}(v::Set{T}) = collect(v) # overloading 'JSON.lower' println(json(Set([1,2,1]))) ## output: ## [2,1] JSON.print(Set([1,2,1])) ## output still: ## {"dict":{"2":null,"1":null}} end # module - 那么这个方法已经编译好了,并且不会使用我的'JSON.lower'扩展
  • 这实际上发生在我身上并且难以调试,因为json(v::Set{T})调用的行为符合预期,而json()表现不同(仅通过某些运行流程中的更改)
  • 由于任何模块(这里是JSON.jl)可以被我正在使用的另一个包使用 - 我无法知道我的代码实际上是先运行并且实际上正确地扩展了一个方法

那么 - 确保这一点的最佳做法是什么?

[目前使用Julia 0.4.6和0.5.0测试此行为]

1 个答案:

答案 0 :(得分:3)

是的,您对Julia 0.5及之前的分析是正确的。许多开发人员都清楚地知道这个问题的编号(#265)。为即将推出的0.6版本进行了大量工作。 Julia现在跟踪每个函数的调用者并根据需要重新编译它们。

一般来说,这里最好的建议是直接修补库并推动你的改变。这在0.5和0.6都是如此,即使运行时正确性修复也是如此。建议您不要使用自己未定义的类型扩展导入的函数,因为它会改变所有依赖于它的其他包的行为。这已经被俗称为“类型盗版”,因为你为了自己的目的而扼杀了这种方法 - 这些目的可能不适合其他来电者。

作为一种临时解决方法,您可以尝试将定义添加到~/.juliarc.jl file,这将在启动时执行,并且在编译任何其他方法之前更有可能被定义。但是,即使这不是防弹,因为软件包可以使用预编译来加速其使用。