Including modules in Julia v0.7


#1

I am trying to update some of my code to make it work with Julia v0.7.0-beta2.0.

I am a bit confused about what is the right way to include a bunch of modules that refer to each other.

Assume I have three files that each contain a module:

1. Module: Types.jl
(a module that holds struct definitions)

module Types

export TwoNumbers

  mutable struct TwoNumbers
    a::Int64
    b::Int64
  end


end

2. Module: Operations.jl
(a module that contains certain functions that work on the custom structs defined in Module 1)

module Operations
using Types
export switchNumbers!
  function switchNumbers!(tn::Types.TwoNumbers)
    a = copy(tn.a)
    b = copy(tn.b)

    tn.a = b
    tn.b = a
    return nothing
  end

end

3. Module MainModule.jl
( a parent module that uses the operations from module 2)

include("./Types.jl")
include("./Operations.jl")

module MainModule
  using Operations, Types

  export performOperation

  function performOperation()
    tn = TwoNumbers(1,2)

    println("Original object: a=$(tn.a), b=$(tn.b)")
    switchNumbers!(tn)
    println("After switching: a=$(tn.a), b=$(tn.b)")
  end

end

Output of the following commands in Julia 0.6.0:

include("MainModule.jl")
MainModule.performOperations()

>>>Original object: a=1, b=2
>>>After switching: a=2, b=1

However, with Julia v0.7.0-beta2.0, I get:

ERROR: LoadError: LoadError: ArgumentError: Package Types not found in current path:
 - Run `Pkg.add("Types")` to install the Types package.

Stacktrace:
 [1] require(::Module, ::Symbol) at ./loading.jl:816
 [2] include at ./boot.jl:317 [inlined]
 [3] include_relative(::Module, ::String) at ./loading.jl:1034
 [4] include(::Module, ::String) at ./sysimg.jl:29
 [5] include(::String) at ./client.jl:393
 [6] top-level scope at none:0
 [7] include at ./boot.jl:317 [inlined]
 [8] include_relative(::Module, ::String) at ./loading.jl:1034
 [9] include(::Module, ::String) at ./sysimg.jl:29
 [10] include(::String) at ./client.jl:393
 [11] top-level scope at none:0
in expression starting at /<PATH>/TestModules/Operations.jl:2
in expression starting at /<PATH>/TestModules/MainModule.jl:2

My question is: What is the best practice to include several files with modules and interdependencies into a parent module MainModule.jl (in Julia 0.7)?


#2

Try .Types instead and perhaps put the includes in the main module.


#3

Thank you. That doesn’t seem to help.


#4

Try

include("Types.jl")
using Types
include("Operations.jl")
using Operations

Also see the package https://github.com/simonster/Reexport.jl
, it can help with something.


#5

Oh you have using Types in Operations.jl.

Do

using ..Types

in Operations.jl and

module MainModule
  include("./Types.jl")
  include("./Operations.jl")
  using .Operations, .Types
  ...
end

in MainModule.jl


#6

Previously packages were stored in Main and as a side effect modules defined in Main could be loaded as if they were packages. That is no longer the case: packages are not stored in Main and you cannot load modules defined in Main that way. In 0.7 import X can only be used to load actual packages (via LOAD_PATH etc. as described in code loading). Now if you want to load a module defined in Main from Main you have to load it with import .X; to load it from a submodule of Main you have to do import ..X.


#7

I have a follow-up question then. I have been developing code with modules in files in the same folder with the module name, where the “using TheModule” mechanism used to work. It appears that starting with Julia 0.7, I cannot find a way to load these local modules without doing include() at some point. The problem with this is that if Module1 is a file and both Module2 and Module3 use Module1, I could previously just do using in both of those and now I have to introduce some mechanism to try and do include outside to avoid loading the module twice.

Am I overlooking something or is what I’m doing just an antipattern? If the latter, how should I approach the situation differently?


#8

That’s the way to do it for now. There’s a plan to allow omitting the include for local imports here: https://GitHub.com/JuliaLang/julia/issues/4600.


#9

Alright, thanks for the quick reply and for pointing me to that issue, I was not aware of that discussion.