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.
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
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.