Skip to content

Commit

Permalink
Amplify the README
Browse files Browse the repository at this point in the history
  • Loading branch information
timholy committed Jun 29, 2017
1 parent 6096f32 commit 3fe9af6
Showing 1 changed file with 75 additions and 8 deletions.
83 changes: 75 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,22 @@

[![codecov.io](http://codecov.io/github/timholy/Revise.jl/coverage.svg?branch=master)](http://codecov.io/github/timholy/Revise.jl?branch=master)

`Revise.jl` makes it easier to continuously update your code in a
running Julia session. If you've said `using Revise` in a Julia
session, you can edit the source files of packages and expect that
most changes will be activated the next time you issue a command from
the REPL.
`Revise.jl` makes it easier to continuously update code in a running
Julia session. If you've said `using Revise` in a Julia session, you
can edit the source files of packages and expect that many changes
will be activated when you next issue a command from the REPL.

The practical consequence is that `Revise` may reduce the number of
times that you'll need to restart your Julia session. This can
increase productivity because the cost of loading packages and JITting
code can be noticeable.

### Example:

```julia
julia> Pkg.add("Example")
INFO: Installing Example v0.4.1
INFO: Package database updated
INFO: METADATA is out-of-date — you may not have the latest version of Example
INFO: Use `Pkg.update()` to get the latest versions of your packages

julia> using Revise # importantly, this must come before `using Example`

Expand All @@ -40,7 +42,24 @@ Julia's `Base` module: just say `Revise.track(Base)`. You'll see
warnings about some files that are not tracked (see more information
below).

## Using Revise automatically
## Manual revision

There might be times where you'd prefer to exert manual control over
the timing of revisions. `Revise` looks for an environment variable
`JULIA_REVISE`, and if it is set to anything other than `"auto"` it
will avoid making automatic updates each time you enter a command at
the REPL. You can call `revise()` whenever you want to process
revisions.

On Linux, you can start your Julia session as

```sh
$ JULIA_REVISE=manual julia
```

and then revisions will be processed only when you call `revise()`.

## Using Revise by default

If you like Revise, you can ensure that every Julia session uses it by
adding the following to your `.juliarc.jl` file:
Expand All @@ -52,6 +71,50 @@ adding the following to your `.juliarc.jl` file:
end
```

## How it works

Revise is based on the fact that you can change functions even when
they are defined in other modules:

```julia
julia> convert(Float64, π)
3.141592653589793

julia> # That's too hard, let's make life easier for students

julia> eval(Base, quote
convert(::Type{Float64}, x::Irrational{:π}) = 3.0
end)
WARNING: Method definition convert(Type{Float64}, Base.Irrational{}) in module Base at irrationals.jl:130 overwritten at REPL[2]:2.
convert (generic function with 700 methods)

julia> convert(Float64, π)
3.0
```

Revise removes some of the tedium of manually copying and pasting code
into `eval` statements. To decrease the amount of re-JITting
required, rather than reloading the entire package Revise takes care
to `eval` only the *changes* in your package(s). To accomplish this,
it uses the following overall strategy:

- add a callback to Base so that Revise gets notified when new
packages are loaded
- parse the source code for newly-loaded packages to determine the
module associated with each line of code, as well as the list of
`include`d files; cache the parsed code so that it is possible to
detect future changes
- monitor the file system for changes to any of the `include`d files;
append any updated files to a list of file names that need future
processing
- intercept the REPL's backend to ensure that the list of
files-to-be-revised gets processed each time you execute a new
command at the REPL
- when a revision is triggered, the source file(s) are re-parsed, and
a diff between the cached version and the new version is
created. `eval` the diff in the appropriate module(s).
- replace the cached version of each source file with the new version.

## Caveats

`Revise` only tracks files that have been required as a consequence of
Expand All @@ -66,3 +129,7 @@ There are some kinds of changes that Revise cannot incorporate into a running Ju
- changes in files that are omitted by Revise (you should see a warning about these). Revise has to be able to statically parse the paths in your package; statements like `include("file2.jl")` are easy but `include(string((length(Core.ARGS)>=2 ? Core.ARGS[2] : ""), "build_h.jl"))` cannot be handled.

These kinds of changes require that you restart your Julia session.

## Credits

Revise became possible because of Jameson Nash's fix of [Julia issue 265](https://github.com/JuliaLang/julia/issues/265).

0 comments on commit 3fe9af6

Please sign in to comment.