Modules
Prerequisites: Functions
A module is a separate namespace for code. Every package is a module, and you can define your own:
module Geometry
export area, Circle
struct Circle
r::Float64
end
area(c::Circle) = π * c.r^2
circumference(c::Circle) = 2π * c.r # not exported
end # module
using .Geometry
c = Circle(2)
println(round(area(c), digits = 3))
println(round(Geometry.circumference(c), digits = 3))
12.566
12.566
exportlists the names thatusingbrings into scope.- Non-exported names are still reachable with
Module.name. using .Geometry— the dot means "a module defined here", not an installed package.
using versus import
module Greetings
export hello
hello(name) = "Hello, $name"
secret() = "hidden"
end
import .Greetings
println(Greetings.hello("Ada"))
using .Greetings: hello
println(hello("Grace"))
import .Greetings as G
println(G.secret())
Hello, Ada
Hello, Grace
hidden
| Statement | Effect |
|---|---|
using Mod |
Brings in Mod and all its exported names |
using Mod: a, b |
Brings in only a and b |
import Mod |
Brings in only the name Mod; use Mod.f |
import Mod as M |
Same, under a shorter name |
import Mod: f |
Brings in f and allows adding methods to it |
Many style guides prefer using Mod: a, b in packages, so it's clear
where each name comes from.
Splitting code across files
include("file.jl") runs another file's code as if it were pasted in.
A typical package module looks like this:
# illustrative — src/Inventory.jl
module Inventory
export Item, add_item!, total_value
include("types.jl") # defines Item
include("operations.jl") # defines add_item!, total_value
end
Each file is included once, from the module file. Don't include
the same file from several places — that defines things twice.
Main and Base
Code you run in the REPL or a script lives in the module Main.
Julia's built-in functions live in Base (and standard libraries like
LinearAlgebra are modules too) — that's why you write
Base.show(...) when adding a method to show.