IMPORTANT: ClobberingReload.jl has been superseded by Revise.jl. Please consider using this package from 0.6 onward. ClobberingReload.jl is no longer actively developed (though pull requests are welcome).
ClobberingReload.jl
ClobberingReload.jl
helps with interactive development.
creload(::Module)
is a drop-in replacement forreload(modulename)
, that does not require rebuilding the state afterreload
. The new code takes effect immediately, and works on existing objects.- Modules loaded with
@ausing
and@aimport
are automatically reloaded when they are modified. This works as a successor to @malmaud's Autoreload.jl package. scrub_stderr
,scrub_redefinition_warnings
andno_warnings
run code with some warnings silenced.
See below for usage information, and the docstrings for details (eg. ?creload
)
ClobberingReload borrows some code and interface from Autoreload.jl by Jon Malmaud, and from Revise.jl by Tim Holy (which offers similar functionality under a different interface).
creload
Using Interactively (whether in the REPL, Atom, or IJulia):
using ClobberingReload
using Houses # `using` modules is fine (unlike with `reload`)
h = House(nwindows=10)
println("Price of house:$(price(h))")
> Price of house: 100
.... modify Houses.jl, change the `price` function ....
creload(Houses)
println("Price of house:$(price(h))") # no need to redefine h
> Price of house: 130
NOTE: Parametric types cannot be defined inside a creload
ed module on Julia 0.5.
This is fixed on Julia 0.6. Parametric type aliases are still a problem, but there is an experimental
alternative that should solve this: creload_strip(module)
. Please
report any issues.
Autoreload
In IJulia (Jupyter notebooks), creload
will be called
automatically for modules that were imported using @ausing
or @aimport
,
whenever the module's source code has been changed.
using ClobberingReload
using Images # regular using
@ausing Foo # autoreloaded using
@aimport Bar # autoreloaded import
@ausing Car <: (Foo, Bar) # autoreloaded with dependency: whenever Car, Foo, or Bar
# are modified, Car will be reloaded
println(Bar.life_the_universe())
> 5
# ... modify Bar.jl, or one of its `include`d files
println(Bar.life_the_universe())
> INFO: Reloading `Bar`
> 42
The Julia REPL does not have execution hooks yet, but you can still trigger the autoreload feature for @aimport
ed modules by calling areload()
manually. Or you can use Revise.jl, which works around this issue by scheduling a background thread.
Silencing warnings
scrub_stderr
, scrub_redefinition_warnings
and no_warnings
silence some of
Julia's warnings. Typical usage:
scrub_redefinition_warnings() do
include(filename)
end
sinclude("foo.jl")
uses the above code to runinclude("foo.jl")
without the usual redefinition warnings.scrub_stderr
can scrub arbitrary warnings using regexes. See its docstring for details.
creload
works
How Julia's reload(mod)
loads mod
from scratch, creating a new module object,
then replaces the old module object with the new one. As a consequence:
import A
st = A.SomeType(10)
reload("A")
st2 = A.SomeType(10)
typeof(st) == typeof(st2) # false
st
and st2
are actually of a different type, and cannot be equal. Functions
defined on the first ::A.SomeType
will not work on the second, and vice
versa. This is inconvenient when working interactively.
ClobberingReload.creload
solves this problem by never creating a second
module. It just evaluates the modified code inside the existing module object,
replacing the previous definitions.
using ClobberingReload
import A
st = A.SomeType(10)
creload(A)
st2 = A.SomeType(10)
typeof(st) == typeof(st2) # true
Furthermore, reload
cannot reload modules imported via using
, but creload
can.