On writing modules using functions from other packages

I’m trying to write a module for data visualization that uses the function Gray from the package Images.jl. From what I gather, this should have been a matter of creating my module and “calling” the other package and its function, like I do when I use them on my code (pretty intuitive so far). Something like this:

module MyModule

using Images: Gray 
export fv, fm

function fv(v::Vector)
   return Gray.(v)
end

function fm(m::Matrix)
   return Gray.(m)
end

end 

Then, when I want to use my module, I just need to add the path to it’s location on the LOAD_PATH variable, like this push!(LOAD_PATH, "/home/bruno/Documents/juliautils/mymodules") and then I can call using MyModule and my functions feeling like a pro.

The story above works great when I’m not calling packages inside my module. But I’m not that lucky with complicated things like Images or Plots. Maybe that’s because Images.jl is a “umbrella package” (like they say in the docks somewhere) that calls many other things and this process is not chained together when you use it like I’m trying to… maybe (probably) I’m doing something other the wrong way, like files in the wrong place or whatever.

My point is, making Modules feels like a good way to create a customized toolbox for my day to day needs without all the fuzz of creating a package. After all, my day-to-day functions may not be useful for anyone else. All of that to say I feel this should be a simple process, but I’m not figuring this out by myself. Any suggestion would be appreciated.

I’m guessing your problems arise from trying to load this module from an environment where Images.jl isn’t available as a dependency. At the very least, it’s important to work within a reproducible project environment where you can specify necessary dependencies, but it’s almost always easier in the long run to just incorporate your functions into a dedicated package. There’s no need to publish your package in Julia’s General package repository, but Julia’s tooling is built around its package manager, and you’ll benefit by adopting the same package-centric workflow assumed by the tooling. See this tutorial for a brief introduction to DIY packages.

2 Likes

If you add the dependencies (Images, here) to the main environment, that should work.

This is a reasonable solution while the number of packages is not too great (I have Plots and a bunch of other packages installed in the main environment, exactly for wanting to use them eventually in other places).

Other alternatives can be to have one package with your inhouse functions.

Or, depending on what you are doing, you can create an environment just for running your module, using something like:

import Pkg
Pkg.UPDATED_REGISTRY_THIS_SESSION[] = true
Pkg.activate(temp=true)
Pkg.add(name="Images")
push!(LOAD_PATH, "/home/bruno/Documents/juliautils/mymodules")
using MyModule

The second line avoids the registry to be updated and thus the subsequent “adding” of the package Images is fast. This is practical, actually, but it prints a bunch of stuff to the screen (maybe there is an option to Pkg to work silently).

1 Like