Standard modules and paths

The code for Julia packages (also called libraries) is contained in a module whose name starts with an uppercase letter by convention, like this:

# see the code in Chapter 6modules.jl
module Package1

export Type1, perc

include("file1.jl")
include("file2.jl")

# code
mutable struct Type1
total
end

perc(a::Type1) = a.total * 0.01

end

This serves to separate all its definitions from those in other modules so that no name conflicts occur. Name conflicts are solved by qualifying the function by the module name. For example, the packages Winston and Gadfly both contain a function plot. If we needed these two versions in the same script, we would write it as follows:

import Winston
import Gadfly
Winston.plot(rand(4))
Gadfly.plot(x=[1:10], y=rand(10))

All variables defined in the global scope are automatically added to the Main module. Thus, when you write x = 2 in the REPL, you are adding the variable x to the Main module.

Julia starts with Main as the current top-level module. The module Core is a set of non-Julia sources (in the src directory of the GitHub source); for example, C/C++ and Femtolisp, which are used to create libjulia, are used by the Julia source to interface to the OS through the API. The standard library is also available. The code for the standard library (the contents of /base) is contained in the following modules:

  • Base64
  • FileWatching
  • LinearAlgebra
  • Printf
  • Serialization
  • SuiteSparse
  • CRC32c
  • Future
  • Logging
  • Profile
  • SharedArrays
  • Test
  • Dates
  • InteractiveUtils
  • Markdown
  • REPL
  • Sockets
  • UUIDs
  • DelimitedFiles
  • LibGit2
  • Mmap
  • Random
  • SparseArrays
  • Unicode
  • Distributed
  • Libdl
  • Pkg
  • SHA 
  • Statistics

The type of a module is Module: typeof(Base), which returns Module. If we call names(Main), we get, for example, 5-element Array{Symbol,1}: :ans, :Main, :Core, :Base, and :InteractiveUtils. If you have defined other variables or functions in the REPL, these would also show up.

All the top-level defined variables and functions, together with the default modules, are stored as symbols. The varinfo() function lists these objects with their types:

name                size     summary
–––––––––––––––– ––––––––––– –––––––
Base Module
Core Module
InteractiveUtils 157.063 KiB Module
Main Module

This can also be used for another module. For example, varinfo(Winston) lists all the exported names from the module Winston.

A module can make some of its internal definitions (such as constants, variables, types, functions, and so on) visible to other modules (as if making them public) by declaring them with export. This can be seen in the following example:

export Type1, perc

For the preceding example, using Package1 will make the type Type1 and function perc available in other modules that import them through this statement. All the other definitions remain invisible (or private).

As we saw in Chapter 1, Installing the Julia Platform, a module can also include other source files in their entirety with include("file1.jl"). However, this means that the included files are not modules. Using include("file1.jl") is, to the compiler, no different from copying file1.jl and pasting it directly in the current file or the REPL.

In general, use import to import definitions from another module in the current module:

  • After import.LibA, you can use all definitions from LibA inside the current module by qualifying them with LibA., such as LibA.a

  • The import LibB.varB or import LibD.funcD statement only imports one name; the function funcD must be used as LibD.funcD.

  • Use importall LibE to import all the exported names from LibE in the current module.

Here is a more concrete example. Suppose we define a TemperatureConverter module as follows:

#code in Chapter 6	emperature_converter.jl
module TemperatureConverter

function as_celsius(temperature, unit)
if unit == :Celsius
return temperature
elseif unit == :Kelvin
return kelvin_to_celsius(temperature)
end
end

function kelvin_to_celsius(temperature)
# 'private' function
return temperature + 273
end

end

We can now use this module in another program as follows:

#code in Chapter 6using_module.jl
include("temperature_converter.jl")

println("$(TemperatureConverter.as_celsius(100, :Celsius))")
#> 100
println("$(TemperatureConverter.as_celsius(100, :Kelvin))")
#> 373
println("$(TemperatureConverter.kelvin_to_celsius(0))") #> 273

Imported variables are read-only, and the current module cannot create variables with the same names as the imported ones. A source file can contain many modules, or one module can be defined in several source files. If a module contains a function __init__(), this will be executed when the module is first loaded.

The variable LOAD_PATH contains a list of directories where Julia looks for (module) files when running the using, import, or include statements. Put this statement in the file ~/.julia/config/startup.jl to extend LOAD_PATH on every Julia startup:

push!(LOAD_PATH, "new/path/to/search")

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.76.138