"contour not defined" when using my package

Hello,

I am building a new package for the first time, and I’m running into a problem when I call one of the functions exported by my package, SimpleNavierStokes.jl.

The package exports a function, LidDrivenCavity(). This function returns an object of type Results, which I have defined inside the SimpleNavierStokes module like this:

struct Results
    ψ::Array
    ω::Array
    hist::Array
    x::Array
    y::Array
    ...
end

This works as expected. Next, I have defined a custom “plotting function”. Rather than redefining plot() with my new type Results, I decided to define my own function, which does something like this:

ShowStreamlines(sol::Results) = contour(sol.x,sol.y,sol.ψ)

(I have also tried replacing sol::Results with sol:SimpleNavierStokes.Results; this doesn’t appear to help.) Aside: I know this looks like a trivial function, but I plan to make it more useful and so I would like to do something like this rather than expecting the user to call plot on the different constituent parts of Results.

This function does get exported, but when I call it on an object of type Results, like this:

Pkg.add("https://github.com/emadmasroor/SimpleNavierStokes.jl")
using Plots, SimpleNavierStokes
a = LidDrivenCavity()
ShowStreamlines(a)

I get:

ERROR: UndefVarError: contour not defined
Stacktrace:
 [1] ShowStreamlines(::Results) at /home/emad/.julia/packages/SimpleNavierStokes/JTjDG/src/plot_utils.jl:12
 [2] top-level scope at REPL[26]:1

Just to be clear, my REPL does recognize the function contour, because immediately after the above, if I type:

contour

I get the expected: contour (generic function with 1 method).

Why does this happen, and how can I fix it? I don’t think I should have to put a using Plots inside my own package, other packages don’t really do this. But why does my code not recognize contour, when my current environment contains Plots and the functions are immediately available?

Note: If I subsequently define a function like ShowStreamlines inside the REPL, say by doing this at the REPL

Show2(sol::SimpleNavierStokes.Results) = contour(sol.x,sol.y,sol.ψ)
Show2(a)

it works as expected, and I get the output of the contour plot. So I am probably doing something wrong inside my package.

I appreciate any help!

Some one can correct me, but I think you need to either have the Plots dependency (i.e. using Plots) or import it directly if you want to eventually overload it. Right now, your Module dosn’t know about the function contour since you havn’t defined or imported the method anywhere within the scope of your module. Ask yourself, is SimpleNavierStokes.contour() defined anywhere?

The reason it works in the REPL is because the REPL module scope is Main and you are indeed bringing in the contour function by using Plots.

Okay, this explanation makes sense - I’ll add using Plots inside my module, then. I guess I was expecting that, when a function like ShowStreamlines is called, the scope from which you call it would also be seen by the code inside that function. But it makes sense that this is not the case.

Thanks for your help!