Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the right way to write a module finalize method in Julia?

Tags:

julia

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 TestModule

then 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 passed

after 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 defined 

According to above test cases I have some questions

  1. Why adding such finalize method for TestModule generates ERROR during test process?

  2. Why finalize method was not called while I clear references

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

like image 846
Reza Afzalan Avatar asked Oct 25 '15 06:10

Reza Afzalan


1 Answers

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 happened

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

like image 88
Maciek Leks Avatar answered Oct 08 '22 12:10

Maciek Leks