I want to make an application. So I do cd ; julia and then switch to Pkg mode and use generate to generate my application.
I then have a src/app.jl. Now I want to add a few files that do some fancy stuff. Apparently, I could use include to load those files but that’s bad because Revise doesn’t recognize it. The proper way is to make a module.
So I scope my files with the module keyword. Now I want to use them, but how?
Let’s say I have the following in my src/
main.jl
module test
# How to lod myPlot module here?
end # module
myPlot.jl
module myPlot
using Plots
function plotSine()
x = LinRange(0,1,11)
y = sin.(x)
gr()
p = plot(x,y, title="hi test 2")
plot!(p,x,y.*2)
display(p)
end
end
The only valid workflow I found consists of using Revise and Revise works with includet and not with include. Now I don’t want to clutter my codebase with includets, so I have to use a module. I can’t help it, that’s how Julia works.
Of course I know about includet. Now I could includet myPlot.jl separately and test it separately but that just seems wrong because the file might not be isolated like that. So currently I can’t see how anyone would ever use include in their code, forcing me to make everything a module.
I don’t like this idea sorry. I don’t want to use environment variables for loading modules. That just seems weird. Ther’es a Project.toml and a Manifest.toml which should take care of such things, no?
But I agree that registering the module correctly is probably my issue here.
Except what other said: It’s weird to use a module for everything.
Do ]dev . in your package environment. That way using MyPackage is visible everywhere and you can do using MyPackage inside your testing module
I think there is some confusion about what
# test/runtests.jl
module test
include("MyPackage.jl")
using .MyPackage
end
does. When do include("test/runtests.jl") this will overwrite the last test module and load a new one. This means that any changes to MyPackage get brought in when you run the tests. So it will always be up to date.
LOAD_PATH is not a variable you set in your .login file. It’s easier than that and works well with the toml files.
If you projects/modules … live in Module_Directory, all you need to do is type
push!(LOAD_PATH," Module_Directory")
in the REPL or, better yet, put it in your .startup.jl file. You’ll never have to think about it again. Doing this enables Julia to find things in Project/src directories with ease.
Maybe I am missing the point but this works for me:
main.jl:
module myMain
# How to lod myPlot module here?
include("myPlot.jl")
using .myPlot
end # module
myPlot.jl:
module myPlot
using Plots
function plotSine()
x = LinRange(0,1,11)
y = sin.(x)
gr()
p = plot(x,y, title="hi test 2")
plot!(p,x,y.*2)
display(p)
end
end
Perhaps the example you are providing is not representative of what you want. But:
the code of the plotSine() function could well be in the global scope. That is, you could have a file name “plotsine.jl” with that code inside (without the function ... end. You can include that file using include(), see the plot, and if you want to modify its content, just modify it and include the file again. You don’t need any module for that, and you do not need revise for that either.
You may have several functions in the same file, let say, file myfuncs.jl, with:
f(x) = x + 1
g(x) = abs(x)
h(x) = 2*x
You then can include that file directly and use those functions. If you modify that file, just include it again and the methods will be overwritten. Again, no module or Revise need for now.
A slightly more sophisticated approach is to use Revise and includet. Instead of including again the file after each modification, use includet(myfuncs.jl). The modifications of the file will tracked. You only need oneincludet, which is being used in the REPL where you are working, no includets will permeate your code anywhere.
You can includet(myPlots.jl) and that will track the modifications of that file (no additional module layer, like your main, needed there).
Finally, I do agree that there is a problem in that Revise does not track the modifications of a include()d file within a a file which was itself included with includet. It does track the modifications if the file is included (with include()) within a package. For greater projects in which it is natural that one has a properly organized project, one would use Revise and using MyProject, and the files included with include() anywhere within that projects are tracked by revise. This is the most common workflow (I think) for larger projects.
julia> using Revise
julia> includet("./MyModule.jl")
julia> MyModule.f(1)
2
shell> vim mycode.jl # changed the behaviour of f(x) inside mycode.jl
julia> MyModule.f(1) # the change in f was not tracked
2
julia>
I think this is an issue. Perhaps someone can explain if there is a reason for the file not being tracked, or if we should file an issue.
EDIT: According to this post:
includet is thought to track only the file itself. The workflow that is recommended is that of @ctkelley, meaning, if the module is in the current directory:
using Revise
push!(LOAD_PATH,"./")
using MyModule
Not bad. One can add this push!(LOAD_PATH,"./") to the startup.jl file and then just use the modules in the current working directory directly.
The other method is via Pkg, attached my installation description, as I do not know how to attach documents here, the description is added in form of figures: