How to reload a module in an active Julia session after editing?

2018 update: be sure to check all the answers, as the answer to this question has changed several times over the years. At the time of this update, Revise.jl answer Revise.jl probably the best solution.

I have a file "/SomeAbsolutePath/ctbTestModule.jl" whose contents are:

 module ctbTestModule export f1 f1(x) = x + 1 end 

I run Julia in a terminal that runs "~ / .juliarc.jl". The startup code includes the line:

 push!(LOAD_PATH, "/SomeAbsolutePath/") 

Therefore, I can immediately type in the console Julia:

 using ctbTestModule 

download my module. As expected, f1(1) returns 2 . Now I suddenly decided that I want to edit f1 . I open "/SomeAbsolutePath/ctbTestModule.jl" in the editor and change the contents to:

 module ctbTestModule export f1 f1(x) = x + 2 end 

Now I'm trying to reload the module in my active Julia session. I'll try

 using ctbTestModule 

but f1(1) still returns 2 . Next I try:

 reload("ctbTestModule") 

as suggested here , but f1(1) still returns 2 . Finally, I try:

 include("/SomeAbsolutePath/ctbTestModule.jl") 

as suggested here , which is not ideal since I have to enter the full absolute path, since the current directory may not be β€œ/ SomeAbsolutePath”. I get a warning message Warning: replacing module ctbTestModule which sounds promising, but f1(1) still returns 2 .

If I using ctbTestModule current Julia session, start a new one and using ctbTestModule , I will get the desired behavior, i.e. f1(1) will return 3 . But obviously, I want to do this without restarting Julia.

So what am I doing wrong?

Other details: Julia v0.2 on Ubuntu 14.04.

+54
module julia-lang julia
Jul 30 '14 at 4:39
source share
5 answers

The basis of this problem is the merge of the module reload, but it is not able to redefine the thing in the Home module ( see the documentation here ) - this is at least until the new workspace () becomes available on July 13, 2014. Recent versions of pre-release 0.3 should have it.

To workspace ()

Consider the following simplified module

 module TstMod export f function f() return 1 end end 

Then use it ....

 julia> using TstMod julia> f() 1 

If the function f () is changed to return 2 and the module is reloaded, f is actually updated. But it is not redefined in the Home module.

 julia> reload("TstMod") Warning: replacing module TstMod julia> TstMod.f() 2 julia> f() 1 

The following warnings fix the problem.

 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 

Use workspace ()

However, the new workspace () function clears the Home , preparing it to restart TstMod

 julia> workspace() julia> reload("TstMod") julia> using TstMod julia> f() 2 

In addition, the previous Main is stored as LastMain

 julia> whos() Base Module Core Module LastMain Module Main Module TstMod Module ans Nothing julia> LastMain.f() 1 
+52
Aug 01 '14 at 10:04 on
source share

In my humble opinion, it is best to use import from the very beginning rather than using for the reported problem.

Consider the module:

 module ModuleX1 export produce_text produce_text() = begin println("v1.0") end println("v1.0 loaded") end 

Then in the REPL:

 julia> import ModuleX1 v1.0 loaded julia> ModuleX1.produce_text() v1.0 

Update the module code and save it:

 module ModuleX1 export produce_text produce_text() = begin println("v2.0") end println("v2.0 loaded") end 

Further in the REPL:

 julia> reload("ModuleX1") Warning: replacing module ModuleX1 v2.0 loaded julia> ModuleX1.produce_text() v2.0 

Benefits of using import over using :

  • Avoid ambiguity in function calls (what to call: ModuleX1.produce_text () or product_text () after a reboot?)
  • no need to call workspace() to get rid of the ambiguity

Disadvantages of using import before using :

  • a full name is required in each call for each exported name

Edited: excluded "full access to the module, even to unexported names" from "Disadvantages ..." according to the conversation below.

+10
Aug 12 '15 at 13:27
source share

Use the Revise package, for example,

 Pkg.add("Revise") # do this only once include("src/my_module.jl") using Revise import my_module 

You may need to start this in a new REPL session. Note the use of import instead of using , because using does not override the function in the Main module (as explained by @Maciek Leks and @waTeim).

Other solutions : Two advantages of Revise.jl over workspace() are that (1) it is much faster and (2) it has Revise.jl for the future, since workspace() deprecated in version 0.7, as discussed in this release Github :

 julia> VERSION v"0.7.0-DEV.3089" julia> workspace() ERROR: UndefVarError: workspace not defined 

and a GitHub member recommended Revise.jl :

Should we add a message like "workspace is out of date, check Revise.jl instead"?

Even in Julia 0.6.3, the three previous workspace() solutions, import and reload fail when the DataFrames module DataFrames other modules, such as DataFrames . With all three methods, I got the same error when I called this module a second time in the same REPL:

 ERROR: LoadError: MethodError: all(::DataFrames.##58#59, ::Array{Any,1}) is ambiguous. Candidates: ... 

I also received many warning messages, such as:

 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. 

Restarting Julia's session worked, but it was cumbersome. I found this problem in the Reexport package , with a similar error message:

 MethodError: all(::Reexport.##2#6, ::Array{Any,1}) is ambiguous. 

and followed the suggestion of one participant:

Does this happen without using workspace ()? This feature is notorious for not interacting well with packages, so it is partly outdated in version 0.7.

+10
Jun 12 '18 at 11:40
source share

In julia v0.6.0 it seems that the use of workspace () is no longer : I can just reload (MyModule) in the active REPL session and it works as expected (chages made to the source file containing MyModule are reflected in the active REPL session).

This applies to modules that have been added to scope using import or using

+7
Aug 26 '17 at 8:41 on
source share

I wanted to create a new module from scratch, and tried different answers from 1.0 and did not get a satisfactory result, but I found that the following works for me:

From Julia REPL in the directory that I want to use for my project, I run

 pkg> generate MyModule 

This creates a subdirectory similar to the following structure:

 MyModule β”œβ”€β”€ Project.toml └── src └── MyModule.jl 

I put my module code in MyModule.jl . I have MyModule in the MyModule directory (or open it in my IDE) and add the Scratch.jl file with the following code:

 Pkg.activate(".") using Revise import MyModule 

Then I can add my code to check below, and everything is updated without restarting REPL.

0
May 09 '19 at
source share



All Articles