Errors when re-including modules in REPL

Here’s a minimum working example of the problem I’ve been having. I’m using the Julia v1.1 REPL in Ubuntu Linux 16.04. Suppose I have the following file called moduletest.jl:

module mymodule
    struct mystruct
        myint::Int
    end

    function myfunction(x::mystruct)
        println(x.myint)
    end
end

In the REPL I include this file, create an instance of mystruct, and call myfunction:

julia> include("moduletest.jl")
Main.mymodule

julia> thisstruct = mymodule.mystruct(1)
Main.mymodule.mystruct(1)

julia> mymodule.myfunction(thisstruct)
1

Now if I reinclude the file moduletest.jl (without changing or redefining thisstruct) and call the function myfunction again, I get the following error:

julia> include("moduletest.jl")
WARNING: replacing module mymodule.
Main.mymodule

julia> mymodule.myfunction(thisstruct)
ERROR: MethodError: no method matching myfunction(::Main.mymodule.mystruct)
Closest candidates are:
  myfunction(::Main.mymodule.mystruct) at /media/james/Data/Box Sync/Code/QP_synth/moduletest.jl:11
Stacktrace:
 [1] top-level scope at none:0

To the best of my knowledge, the error is arising because it thinks that thisstruct has the wrong type. When I check the type of thisstruct however, I see the following:

julia> typeof(thisstruct)
Main.mymodule.mystruct

The type looks exactly the same as the type listed in the “Closest candidates” error message. This can be really confusing. If I redefine thisstruct after the second include statement then the function works perfectly. However, I tend to make a lot of incremental edits to modules and reinclude them frequently to test if the changes work. I’d prefer not have to reinstantiate all of my struct instances every time I reinclude a module (if possible). I’d also rather not restart the REPL if possible since it takes a while to reimport all the other packages I’m using. So my questions are:

  1. What’s the best way to reinclude modules in a REPL without running into this issue?
  2. Would it be possible to change the error message for this situation to be more clear about what the problem is?

(Other details if they’re helpful:

  • I’m fairly new to Julia, so I apologize if I’m not understanding something basic here.
  • I tried the minimum example with the Revise.jl package (v2.1.0) and had the same problem occur.)

The type of thisstruct is technically not the same type when you redefine the module:


julia> include("/tmp/moduletest.jl")
Main.mymodule

julia> thisstruct = mymodule.mystruct(1)
Main.mymodule.mystruct(1)

julia> include("/tmp/moduletest.jl")
WARNING: replacing module mymodule.
Main.mymodule

julia> typeof(thisstruct) ≡ mymodule.mystruct
false

even though it does not show when printed. It is the type from the previous incarnation of that module.

The solution is not to reload modules, but use Revise.jl. Then you get a smoother experience.

Incidentally, I would recommend following the common Julia style conventions, eg capitalizing types.

2 Likes

Perfect–I’ll use Revise.jl instead then. Thanks also for the link on Julia styling conventions!