2018年更新:请务必检查所有回复,因为这个问题的答案多年来已经多次改变.在此更新时,Revise.jl答案可能是最佳解决方案.
我有一个文件"/SomeAbsolutePath/ctbTestModule.jl",其内容是:
module ctbTestModule
export f1
f1(x) = x + 1
end
Run Code Online (Sandbox Code Playgroud)
我在一个运行"〜/ .juliarc.jl"的终端中点燃Julia.启动代码包括以下行:
push!(LOAD_PATH, "/SomeAbsolutePath/")
Run Code Online (Sandbox Code Playgroud)
因此我可以立即输入Julia控制台:
using ctbTestModule
Run Code Online (Sandbox Code Playgroud)
加载我的模块.正如预期的f1(1)回报2.现在我突然决定要编辑f1.我在编辑器中打开"/SomeAbsolutePath/ctbTestModule.jl",并将内容更改为:
module ctbTestModule
export f1
f1(x) = x + 2
end
Run Code Online (Sandbox Code Playgroud)
我现在尝试在我的活跃Julia会话中重新加载模块.我试试
using ctbTestModule
Run Code Online (Sandbox Code Playgroud)
但f1(1)仍然返回2.接下来我尝试:
reload("ctbTestModule")
Run Code Online (Sandbox Code Playgroud)
正如这里所建议的,但f1(1)仍然会回归2.最后,我尝试:
include("/SomeAbsolutePath/ctbTestModule.jl")
Run Code Online (Sandbox Code Playgroud)
正如这里所建议的那样,这是不理想的,因为我必须输入完整的绝对路径,因为当前目录可能不是"/ SomeAbsolutePath".我收到的警告信息Warning: replacing module ctbTestModule听起来很有希望,但f1(1)仍然会返回2.
如果我关闭当前的Julia会话,启动一个新会话并输入using ctbTestModule,我现在得到所需的行为,即f1(1)返回3.但显然我想在不重新启动朱莉娅的情况下这样做.
那么,我做错了什么?
其他细节:Ubuntu 14.04上的Julia v0.2.
waT*_*eim 55
这个问题的基础是重新加载模块的汇合,但是无法重新定义模块Main中的东西(参见此处的文档) - 至少在7月13 日新功能工作空间()可用之前 2014年.预发布0.3的最新版本应该有它.
考虑以下简单模块
module TstMod
export f
function f()
return 1
end
end
Run Code Online (Sandbox Code Playgroud)
然后用它....
julia> using TstMod
julia> f()
1
Run Code Online (Sandbox Code Playgroud)
如果函数f()被更改为返回2并且模块被重新加载,则f实际上已更新.但未在模块Main中重新定义.
julia> reload("TstMod")
Warning: replacing module TstMod
julia> TstMod.f()
2
julia> f()
1
Run Code Online (Sandbox Code Playgroud)
以下警告使问题清楚
julia> using TstMod
Warning: using TstMod.f in module Main conflicts with an existing identifier.
julia> using TstMod.f
Warning: ignoring conflicting import of TstMod.f into Main
Run Code Online (Sandbox Code Playgroud)
但是,新函数workspace()清除Main准备重新加载TstMod
julia> workspace()
julia> reload("TstMod")
julia> using TstMod
julia> f()
2
Run Code Online (Sandbox Code Playgroud)
此外,前一个Main存储为LastMain
julia> whos()
Base Module
Core Module
LastMain Module
Main Module
TstMod Module
ans Nothing
julia> LastMain.f()
1
Run Code Online (Sandbox Code Playgroud)
mig*_*rin 16
使用包Revise,例如
Pkg.add("Revise") # do this only once
include("src/my_module.jl")
using Revise
import my_module
Run Code Online (Sandbox Code Playgroud)
您可能需要在新的REPL会话中启动它.注意使用import而不是using,因为using没有重新定义Main模块中的函数(如@Maciek Leks和@waTeim所解释的).
其他解决方案:与之Revise.jl相比的两个优点workspace()是:(1)它更快,(2)它是面向未来的workspace(),正如在这个GitHub问题中所讨论的那样在0.7中被弃用了:
julia> VERSION
v"0.7.0-DEV.3089"
julia> workspace()
ERROR: UndefVarError: workspace not defined
Run Code Online (Sandbox Code Playgroud)
和GitHub的贡献者建议Revise.jl:
我们是否应该添加一些消息,例如"工作空间已弃用,请查看Revise.jl"?
即使在朱莉娅0.6.3,三个以前的解决方案workspace(),import以及reload失败当模块调用其他模块,如DataFrames.使用这三种方法,当我在同一个REPL中第二次调用该模块时,我得到了同样的错误:
ERROR: LoadError: MethodError: all(::DataFrames.##58#59, ::Array{Any,1}) is ambiguous. Candidates: ...
Run Code Online (Sandbox Code Playgroud)
我还收到许多警告信息,例如:
WARNING: Method definition macroexpand(Module, ANY) in module Compat at /Users/mmorin/.julia/v0.6/Compat/src/Compat.jl:87 overwritten in module Compat at /Users/mmorin/.julia/v0.6/Compat/src/Compat.jl:87.
Run Code Online (Sandbox Code Playgroud)
重启Julia会话很有效,但很麻烦.我在Reexport包中发现了这个问题,并出现了类似的错误消息:
MethodError: all(::Reexport.##2#6, ::Array{Any,1}) is ambiguous.
Run Code Online (Sandbox Code Playgroud)
并遵循一位撰稿人的建议:
不使用workspace()会发生这种情况吗?该函数因与软件包交互不佳而臭名昭着,这也是它在0.7中被弃用的部分原因.
Mac*_*eks 10
在我看来,更好的方法是import从一开始就使用而不是using报告的问题.
考虑一下模块:
module ModuleX1
export produce_text
produce_text() = begin
println("v1.0")
end
println("v1.0 loaded")
end
Run Code Online (Sandbox Code Playgroud)
然后在REPL中:
julia> import ModuleX1
v1.0 loaded
julia> ModuleX1.produce_text()
v1.0
Run Code Online (Sandbox Code Playgroud)
更新模块的代码并保存:
module ModuleX1
export produce_text
produce_text() = begin
println("v2.0")
end
println("v2.0 loaded")
end
Run Code Online (Sandbox Code Playgroud)
接下来,在REPL中:
julia> reload("ModuleX1")
Warning: replacing module ModuleX1
v2.0 loaded
julia> ModuleX1.produce_text()
v2.0
Run Code Online (Sandbox Code Playgroud)
使用的优点import在using:
workspace()为了摆脱歧义而打电话使用import过的缺点using:
编辑:根据下面的对话,放弃了"缺点..."中的"完全访问模块,甚至是未导出的名称".
在朱莉娅v0.6.0好像使用工作区()是没有存在的必要:我可以简单地重新加载(MyModule中)在活动REPL会话,它可以作为到包含MyModule的反映在活跃的源文件的预期(chages REPL会议).
这适用于通过导入或使用进入范围的模块