how to properly nest modules in a package

195 views
Skip to first unread message

ggggg

unread,
Jul 22, 2014, 9:04:17 PM7/22/14
to julia...@googlegroups.com
Lets say I'm making a package P.jl.  Inside P I define modules A, B and C all in separate files. I'd like to use C inside of A and B, and export a function from C from P. 

So right now B looks like
include("C.jl")
module B
using C
B body
end

And A looks like
include("C.jl")
module A
using C
A body
end

And P looks like
include("A.jl")
include
("B.jl")
include
("C.jl")
module P
using A,B,C
P body
end

I suspect that I'm doing it wrong for a few reasons.
1. I'm using two lines to get a module instead of one (include + using)
2. I've included C three times in P.
3. Autoreload.jl is complaining 

At the least it seems like I should remove "include("C.jl")" from P, which seems to help.  I'd appreciate some general guidance.

Iain Dunning

unread,
Jul 22, 2014, 9:09:40 PM7/22/14
to julia...@googlegroups.com
module P
  module C
    export foo
    foo() = 2
  end
  module A
    using ..C
  end
  module B
    using ..C
  end
end

Tested with
julia> P.A.C.foo()
2

Tim Holy

unread,
Jul 22, 2014, 9:36:09 PM7/22/14
to julia...@googlegroups.com
module P

include("C.jl")
include("A.jl")
include("B.jl")

end

B.jl:

module B
using ..C

# blah blah
end

--Tim

Tim Holy

unread,
Jul 22, 2014, 9:36:32 PM7/22/14
to julia...@googlegroups.com
Rats, I should check before posting.

--T

ggggg

unread,
Jul 23, 2014, 12:56:08 AM7/23/14
to julia...@googlegroups.com
Ok I see how that works, I wasn't aware of the ..C syntax. That solves the problem asked about, but I'm left with another question. Take for example

module A
module B
foo
()=4
export foo
end
foo
()
end

That doesn't work, I get "ERROR: foo not defined" because foo is not actually in the A namespace. But if I add "using B" I get "ERROR: B not found". So how do I define B inside A, but also have A import the things that B exports?


Mauro

unread,
Jul 23, 2014, 6:36:25 AM7/23/14
to julia...@googlegroups.com
It still needs relative imports with one dot:

julia> module A
       module B
       foo()=4
       export foo
       end
       using .B
       foo()
       end

Which is a bit odd.  Because at the REPL, which is in module Main, this
is not needed.  This both works:

julia> module T
       end

julia> using .T

julia> module U
       end

julia> using U

Does anyone know why this difference is?

Stefan Karpinski

unread,
Jul 23, 2014, 11:30:25 AM7/23/14
to Julia Users
Main is the root module so /T and ./T are the same thing in Main.

Mauro

unread,
Jul 23, 2014, 11:35:30 AM7/23/14
to julia...@googlegroups.com
On Wed, 2014-07-23 at 16:29, Stefan Karpinski <ste...@karpinski.org> wrote:
> Main is the root module so /T and ./T are the same thing in Main.

but doesn't the same hold for any other "folder"?

/MyMod/T and /MyMod/./T are the same thing
--

Stefan Karpinski

unread,
Jul 23, 2014, 11:52:15 AM7/23/14
to Julia Users
Not quite. Note the initial /. When you do `using M` or `import M` it is like `cat /M` – it is relative to the root of the module system, not the current level of module. When you do `using .M` it is like `cat M` or `cat ./M` – it is relative to the current module. Otherwise when you wrote `using Gadfly` in your package, it would go looking for Gadfly inside your current module, which is unlikely to be where it is – unless you happen to have your own submodule called Gadfly, which is, of course, possible. If that's what you wanted, then you would use a relative import: `using .Gadfly`.

Mauro

unread,
Jul 23, 2014, 12:07:24 PM7/23/14
to julia...@googlegroups.com
got it, tnx
--

Stefan Karpinski

unread,
Jul 23, 2014, 12:20:43 PM7/23/14
to Julia Users
For what's it's worth, we originally looked relative first and then absolute, but it was a usability nightmare. This is more explicit and, once you get it, I think much simpler.

ggggg

unread,
Jul 23, 2014, 2:21:18 PM7/23/14
to julia...@googlegroups.com
It makes sense now, thanks.  

Reply all
Reply to author
Forward
0 new messages