I am trying to find the right way to use finalizers in Julia
Refer to Julia documentation:
finalizer(x, function)
Register a function f(x) to be called when there are no program-accessible references to x. The behavior of this function is unpredictable if x is of a bits type.
First I genetated a TestModule standard package with a TestModule.jl
#in TestModule.jl module TestModule end finalizer(TestModule,(t)->println("fin"))and also a runtest.jl
#in runtest.jl using Base.Test using TestModulethen I tried to test Package but I received ERROR while the test was passed:
julia> Pkg.test("TestModule") INFO: Testing TestModule jl_uv_writecb() ERROR: bad file descriptor EBADF jl_uv_writecb() ERROR: bad file descriptor EBADF jl_uv_writecb() ERROR: bad file descriptor EBADF jl_uv_writecb() ERROR: bad file descriptor EBADF jl_uv_writecb() ERROR: bad file descriptor EBADF jl_uv_writecb() ERROR: bad file descriptor EBADF jl_uv_writecb() ERROR: bad file descriptor EBADF jl_uv_writecb() ERROR: bad file descriptor EBADF jl_uv_writecb() ERROR: bad file descriptor EBADF jl_uv_writecb() ERROR: bad file descriptor EBADF INFO: TestModule tests passedafter that I arranged another test case
julia> workspace() # new workspace julia> typeof(TestModule) # make sure *there are no program-accessible references to `TestModule`* ERROR: UndefVarError: TestModule not defined julia> using TestModule julia> finalize(TestModule) fin # finalize method is working julia> typeof(TestModule) Module # make sure *there is program-accessible reference to `TestModule`* julia> workspace() # force clear references julia> typeof(TestModule) # check that *there are no program-accessible references* ERROR: UndefVarError: TestModule not definedAccording to above test cases I have some questions
Why adding such finalize method for TestModule generates ERROR during test process?
Why finalize method was not called while I clear references
What is the right way to add finalize method for a module
(OS=Ubuntu , Julia Version=0.4.0)
EDIT
as @Maciek have mentioned, calling gc() after workspace() also, do not help.
thanks
解决方案IMHO, workspace takes no prisoners and in addition the finalizer works well only on user-defined and composite types.
I've performed some tests. Have a look at my results:
julia> type Foo x Foo(x) = begin obj = new(x); finalizer(obj,(o) -> println("The end.")); return obj end end julia> Foo(1) julia> workspace() julia> gc() Module the end.error in running finalizer: ErrorException("task switch not allowed from inside gc finalizer") The end.error in running finalizer: ErrorException("task switch not allowed from inside gc finalizer")Another test with object defined inside module scope:
julia> module FinMod type T x::Int end finalizer(T(1), (t) -> println("Module the end.")) end FinMod julia> FinMod FinMod julia> workspace() julia> gc() Module the end.error in running finalizer: ErrorException("task switch not allowed from inside gc finalizer")What about functions(first-class objects)?
julia> function foo() println("I'm foo") end foo (generic function with 1 method) julia> finalizer(foo, (f) -> println("foo function is dead now.")) julia> foo foo (generic function with 1 method) julia> workspace() julia> foo ERROR: UndefVarError: foo not defined julia> gc() julia> #nothing happenedSo, to summarize: In my opinion workspace doesn't call finalize. The finalizer function works OK only for user-defined and composite types. It does not work for Module or Function.
Update: I remembered that workspace rewrites previous Main module into LastMain. So even if our module is not accesible from Main it's is still alive inside LastMain scope (the same works for the function which I used above).
更多推荐
在 Julia 中编写模块 finalize 方法的正确方法是什么?
发布评论