Submodules and variable scopes

I have a quick question about sub modules and scope. I have tried to search for similar questions but have not found an answer, so sorry if this has been asked before:

I have created a project directory with the following modules

module Calculator
  
export interest, rate, plusone

include("Plus_one.jl")


"""
    interest(amount, rate)

Calculate interest from an `amount` and interest rate of `rate`.
"""
function interest(amount, rate)
    return amount * (1 + rate)
end

"""
    rate(amount, interest)

Calculate interest rate based on an `amount` and `interest`.
"""
function rate(amount, interest)
    return interest / amount
end

end # module
~               

and the Plus_one.jl is here:

#Plus_one.jl
module Plus_one

export plusone

plusone(x::Int) = x +1

end #module
~                                                                                                                                                                                                                               

From my understanding, include(“Plus_one.jl”) is the equivalent of copy and pasting that code into my Calculator.jl. I export plusone from module Plus_one into the Calculator scope, and then I export it again from there into the scope of whatever uses Calculator.

However, when I start a Julia Project in this directory and “use Calculator” I get unexpected behavior. interest and rate are exported as expected. If I type either “interest” or “rate” into the repl it recognizes it as a function. However if I type plusone into the repl I get an error. It recognizes Calculator.Plus_one.plusone, however, I don’t understand why plusone is not getting exported into the global namespace?

You need using .Plus_one after you do the include bit, I think.

Ok that makes sense. So export statements aren’t “triggered” unless you are using that module

1 Like

However, this brings me to a new issue. If I add that “using” statement Julia informs me that Calculator does not have Plus_one listed as a dependency in the manifests. How can I add a local file to the dependency list? I have my project set to the current working directory, I go into the package manager and type “add path/to/Plus_one.jl” but that doesn’t seem to work!

I can’t replicate your error (just set up my own project and used a sub-module). Do you have the . in there? It needs to be .Plus_one, not just Plus_one.

1 Like

Are you saying that it should be include("./Plus_one.jl") ?

No. Here is the syntax that works for me

module MyPkg

export bb

greet() = print("Hello World!")

include("submod.jl")

using .SubMod

end # module

with submod being

module SubMod

export bb

bb = 1

end

Ok I got it working. Why is the . necessary here? Is it because Submod or in my case Plus_one.jl is not a package, so this lets the repl know it’s just a general script?

Yes. It’s to resolve the exact ambiguity that was causing you problems. The . means that it’s a module that was defined inside the current module, more or less. It’s a bit of a unix-ism, for sure.

Makes perfect sense, thanks!