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
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).
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.
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.
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.
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.