Revise usage: a cookbook
Package-centric usage
For code that might be useful more than once, it's often a good idea to put it in a package. Revise cooperates with the package manager to enforce its distinction between "versioned" and "under development" packages; packages that you want to modify and have tracked by Revise
should be dev
ed rather than add
ed.
You should never modify package files in your .julia/packages
directory, because this breaks the "contract" that such package files correspond to registered versions of the code. In recent versions of Julia, the source files in .julia/packages
are read-only, and you should leave them this way.
In keeping with this spirit, Revise is designed to avoid tracking changes in such files. The correct way to make and track modifications is to dev
the package.
For creating packages, the author recommends PkgTemplates.jl. A fallback is to use "plain" Pkg
commands. Both options are described below.
PkgTemplates
Because PkgTemplates integrates nicely with git
, this approach might require you to do some configuration. (Once you get things set up, you shouldn't have to do this part ever again.) PkgTemplates needs you to configure your git
user name and email. Some instructions on configuration are here and here. It's also helpful to sign up for a GitHub account and set git's github.user
variable. The PkgTemplates documentation may also be useful.
If you struggle with this part, consider trying the "plain" Pkg
variant below.
If the current directory in your Julia session is itself a package folder, PkgTemplates will use it as the parent environment (project) for your new package. To reduce confusion, before trying the commands below it may help to first ensure you're in a a "neutral" directory, for example by typing cd()
at the Julia prompt.
Let's create a new package, MyPkg
, to play with.
julia> using PkgTemplates
julia> t = Template()
Template:
→ User: timholy
→ Host: github.com
→ License: MIT (Tim Holy <tim.holy@gmail.com> 2019)
→ Package directory: ~/.julia/dev
→ Minimum Julia version: v1.0
→ SSH remote: No
→ Add packages to main environment: Yes
→ Commit Manifest.toml: No
→ Plugins: None
julia> t("MyPkg")
Generating project MyPkg:
/home/tim/.julia/dev/MyPkg/Project.toml
/home/tim/.julia/dev/MyPkg/src/MyPkg.jl
[lots more output suppressed]
In the first few lines you can see the location of your new package, here the directory /home/tim/.julia/dev/MyPkg
.
Press ]
to enter the Pkg REPL. Then add the new package to your current environment with the dev
command.
(<environment>) pkg> dev MyPkg # the dev command will look in the ~/.julia/dev folder automatically
Press the backspace key to return to the Julia REPL.
Now let's try it out:
julia> using Revise # you must do this before loading any revisable packages
julia> using MyPkg
[ Info: Precompiling MyPkg [102b5b08-597c-4d40-b98a-e9249f4d01f4]
(It's perfectly fine if you see a different string of digits and letters after the "Precompiling MyPkg" message.) You'll note that Julia found your package without you having to take any extra steps.
Without quitting this Julia session, open the MyPkg.jl
file in an editor. You might be able to open it with
julia> edit(pathof(MyPkg))
although that might require configuring your EDITOR environment variable.
You should see something like this:
module MyPkg
# Write your package code here.
end
This is the basic package created by PkgTemplates. Let's create a simple greet
function to return a message:
module MyPkg
greet() = print("Hello World!")
end # module
Now go back to that same Julia session, and try calling greet
. After a pause (while Revise's internal code compiles), you should see
julia> MyPkg.greet()
Hello World!
From this point forward, revisions should be fast. You can modify MyPkg.jl
quite extensively without quitting the Julia session, although there are some Limitations.
Using Pkg
Pkg works similarly to PkgTemplates
, but requires less configuration while also doing less on your behalf. Let's create a blank MyPkg
using Pkg
. (If you tried the PkgTemplates
version above, you might first have to delete the package with Pkg.rm("MyPkg")
following by a complete removal from your dev
directory.)
julia> using Revise, Pkg
julia> cd(Pkg.devdir()) # take us to the standard "development directory"
(v1.2) pkg> generate MyPkg
Generating project MyPkg:
MyPkg/Project.toml
MyPkg/src/MyPkg.jl
(v1.2) pkg> dev MyPkg
[ Info: resolving package identifier `MyPkg` as a directory at `~/.julia/dev/MyPkg`.
...
For the line starting (v1.2) pkg>
, hit the ]
key at the beginning of the line, then type generate MyPkg
. The next line, dev MyPkg
, is necessary to tell Pkg
about the existence of this new package.
Now you can do the following:
julia> using MyPkg
[ Info: Precompiling MyPkg [efe7ebfe-4313-4388-9b6c-3590daf47143]
julia> edit(pathof(MyPkg))
and the rest should be similar to what's above under PkgTemplates
. Note that with this approach, MyPkg
has not been set up for version control.
If you add
instead of dev
the package, the package manager will make a copy of the MyPkg
files in your .julia/packages
directory. This will be the "official" version of the files, and Revise will not track changes.
includet
usage
The alternative to creating packages is to manually load individual source files. This approach is intended for early stages of development; if you want to track multiple files and/or have some files include other files, you should consider switching to the package style above.
Open your editor and create a file like this:
mygreeting() = "Hello, world!"
Save it as mygreet.jl
in some directory. Here we will assume it's being saved in /tmp/
.
Now load the code with includet
, which stands for "include and track":
julia> using Revise
julia> includet("/tmp/mygreet.jl")
julia> mygreeting()
"Hello, world!"
Now, in your editor modify mygreeting
to do this:
mygreeting() = "Hello, revised world!"
and then try it in the same session:
julia> mygreeting()
"Hello, revised world!"
As described above, the first revision you make may be very slow, but later revisions should be fast.