Question
Is there a way to perform a “proper” import using a local path as an argument?:
import CMDimData
import_by_path joinpath("/path/to/CMDimData/subpkgs/EasyPlotMPL")
Otherwise, does someone have a better suggestion given the problem I have below?
Background/Premise
I have a package providing glue code for a bunch of backends:
(not important, but: GitHub - ma-laforge/CMDimData.jl: Parametric analysis/visualization +continuous-f(x) interpolation)
If a calling module wants to load the glue code for PyPlot (Matplotlib), it simply has to “import” the package in subpkgs/EasyPlotMPL
.
This way, I can limit the direct dependencies of my module, and avoid having julia add/install packages for all the supported plotting backends.
Hack Solution 1: LOAD_PATH
When I import CMDimData
, I could register the subpkgs
directory with Julia’s LOAD_PATH
variable:
push(LOAD_PATH, joinpath(@__DIR__, "../subpkgs"))
That could work: it would add a new search path for packages to Julia’s session. The calling module could then simply do:
import CMDimData
import EasyPlotMPL #Now visible in the search path
The problem is I am changing Julia’s state at a global level, unbeknownst to the user, so I don’t really like this idea.
Hack Solution 2: include
macro
What I am doing now is hacking my way in with include
:
macro includepkg(pkgname::Symbol)
path = realpath(joinpath(rootpath,"subpkgs/$pkgname/src/$pkgname.jl"))
m = quote
if !@isdefined $pkgname
include($path)
$pkgname.__init__()
end
end
return esc(m) #esc: Evaluate in calling module
end
Note that I have to manually __init__()
the module, because only “proper” packages get initialized automatically.
Now, the caller must instead run:
import CMDimData
CMDimData.@includepkg EasyPlotMPL
What I don’t like here is that code gets copied into the caller’s module. That means that each caller module that wants to use my glue code must compile a new instance of it.
On a true package import
, packages get pre-compiled somewhere (where??), and each subsequent call to import
returns a reference to that same “compiled” instance.
So re-compiling the glue code is probably bad because technically, the types declared in these modules would be distinct from each other. Consider this simple example:
module MA
import CMDimData
CMDimData.@includepkg EasyPlotMPL
end
module MB
import CMDimData
CMDimData.@includepkg EasyPlotMPL
end
Now technically, MA.EasyPlotMPL.SomeType != MB.EasyPlotMPL.SomeType
. This might eventually cause unexpected behaviour.