For older versions of Julia, see https://github.com/MikeInnes/Requires.jl/blob/5683745f03cbea41f6f053182461173e236fdd94/README.md
For Julia 1.9 and higher, Package Extensions is preferable; see the Julia manual.
Requires is a Julia package that will magically make loading packages faster, maybe. It supports specifying glue code in packages which will load automatically when another package is loaded, so that explicit dependencies (and long load times) can be avoided.
Suppose you've written a package called MyPkg. MyPkg has core functionality that it always provides;
but suppose you want to provide additional functionality if the Gadfly package is also loaded.
Requires.jl exports a macro, @require, that allows you to specify that some code is conditional on having both packages available.
@require must be within the __init__ method for your module.
Here's an example that will create a new method of a function called myfunction only when both packages are present:
module MyPkg
# lots of code
myfunction(::MyType) = Textual()
function __init__()
@require Gadfly="c91e804a-d5a3-530f-b6f0-dfbca275c004" myfunction(::Gadfly.Plot) = Graphical()
end
end # moduleThe string is Gadfly's UUID; this information may be obtained
by finding the package in the registry (JuliaRegistries for public packages).
Note that the Gadfly.Plot type may not be available when you load MyPkg, but @require
handles this situation without trouble.
For larger amounts of code you can use include as the argument to the @require statement:
function __init__()
@require Gadfly="c91e804a-d5a3-530f-b6f0-dfbca275c004" include("glue.jl")
endand this will trigger the loading and evaluation of "glue.jl" in MyPkg whenever Gadfly is loaded.
You can even use
function __init__()
@require Gadfly="c91e804a-d5a3-530f-b6f0-dfbca275c004" @eval using MyGluePkg
endif you wish to exploit precompilation for the new code.
In the @require block, or any included files, you can use or import the package, but note that you must use the syntax using .Gadfly or import .Gadfly, rather than the usual syntax. Otherwise you will get a warning about Gadfly not being in dependencies.
@required packages can be added to the test environment of a Julia project for integration tests, or directly to the project to document compatible versions in the [compat] section of Project.toml.
For a complete demo, consider the following file named "Reqs.jl":
module Reqs
using Requires
function __init__()
@require JSON="682c06a0-de6a-54ab-a142-c8b1cf79cde6" @eval using Colors
end
endHere's a session that shows how Colors is only loaded after you've imported JSON:
julia> include("Reqs.jl")
Main.Reqs
julia> using Main.Reqs
julia> Reqs.Colors
ERROR: UndefVarError: Colors not defined
julia> using JSON
julia> Reqs.Colors
Colors
julia> Reqs.Colors.RGB(1,0,0)
RGB{N0f8}(1.0,0.0,0.0)Note that if Reqs were a registered package you could replace the first two commands with using Reqs.
In the case that a feature depends on multiple packages, you can do the following trick:
module TestRequires
using Requires
function __init__()
@require Images="916415d5-f1e6-5110-898d-aaa5f9f070e0" begin
@require Revise="295af30f-e4ad-537b-8983-00126c2a3abe" println("Got both!")
end
end
end # moduleThe code will only be loaded in the presence of both Images.jl and Revise.jl:
julia> using TestRequires
[ Info: Precompiling TestRequires [eb9e79a2-1324-11e9-3469-91075b92f61d]
julia> using Images
julia> using Revise
[ Info: Recompiling stale cache file /tmp/pkgs/compiled/v1.0/Revise/M1Qoh.ji for Revise [295af30f-e4ad-537b-8983-00126c2a3abe]
Got both!Other packages can be informed about Requires' actions. To implement this, add a function
add_require(sourcefile, modcaller, id, modname, expr)to your package. The arguments will have the following types:
sourcefile: a string, the full path to the file that contained the@requirestatementmodcaller: the active module from which the@requirewas issuedid: a string representing the UUID of the package that triggered this@requireblock (e.g., the uuid string from@require Gadfly="c91e804a-d5a3-530f-b6f0-dfbca275c004")modname: a string representing the name of the package that triggered this@requireblock (e.g.,"Gadfly"in the example above)expr: the expression in the@requireblock
Once you've added this, append the PkgId of your package to Requires.notified_pkgs
in a pull request to Requires.