How to interactively refer to other modules' type?

I’m confused with interactively referring types across modules.
Here’s my example:

  • src/MyModuleA.jl
module A

using Reexport

include("MyModuleB.jl")
include("MyModuleC.jl")

@reexport using .B
@reexport using .C

end
  • src/MyModuleB.jl
module B


export MyStructB

mutable struct MyStructB
    b
end


end
  • src/MyModuleC.jl
module C

export MyStructC


include("MyModuleB.jl")
using .B

mutable struct MyStructC
    myB::MyStructB
    MyStructC() = init!(new())
end

function init!(myC::MyStructC)
    myC.myB = MyStructB(1.0)
    return myC
end

end
  • test/MyTest.jl
include("../src/MyModuleA.jl")
using .A

myC = MyStructC()
typeof(myC.myB) == MyStructB
  • Result (after running include("test/MyTest.jl")
false  # I expected `MyStructB`, but the type is `Main.A.C.B.MyStructB`

As above, I expected it should be MyStructB but it’s Main.A.C.B.MyStructB.

Anybody can help me?

After reading Reexport’s examples more carefully, I found out what should I do.
I changed a little bit of codes like this and it solves the problem:

  • src/MyModuleA.jl
module A

using Reexport

# include("MyModuleB.jl")
include("MyModuleC.jl")

# @reexport using .B
@reexport using .C

end
  • src/MyModuleB.jl
module B


export MyStructB

mutable struct MyStructB
    b
end


end
  • src/MyModuleC.jl
module C

export MyStructC

using Reexport


include("MyModuleB.jl")
@reexport using .B

mutable struct MyStructC
    myB::MyStructB
    MyStructC() = init!(new())
end

function init!(myC::MyStructC)
    myC.myB = MyStructB(1.0)
    return myC
end

end
  • test/MyTest.jl
include("../src/MyModuleA.jl")
using .A

myC = MyStructC()
typeof(myC.myB) == MyStructB
  • Result (after running include("test/MyTest.jl")
true

It is generally a bad idea to include the same file multiple times.

In MyModuleC you probably should use using ../B. Now you only have one version of B instead of two.

Often (I find) the cleaner alternative is to make B a package (even if it is small) and declare the dependency in A's and C's Project.toml, avoiding all include statements.

I have also found that having lots of sub-modules tends to be more trouble than it’s worth. But I don’t know anything about your project, so my experience may not apply here.

4 Likes