在Julia中编写模块finalize方法的正确方法是什么?

时间:2015-10-25 06:12:06

标签: julia

我正在努力找到在Julia中使用终结者的正确方法

请参阅Julia文档:

  

终结者(x,函数)

     

当没有程序可访问的x引用时,注册要调用的函数f(x)。如果x是位类型,则此函数的行为是不可预测的。

首先,我使用TestModule.jl

生成了一个TestModule标准包
#in TestModule.jl
module TestModule
end
finalizer(TestModule,(t)->println("fin"))

还有runtest.jl

#in runtest.jl
using Base.Test
using TestModule

然后我尝试测试Package但是在测试通过时我收到了ERROR:

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
之后我安排了另一个测试用例

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 

根据上述测试用例,我有一些问题

  1. 为什么在finalize中添加TestModule方法会在测试过程中生成错误?
  2. 为什么在清除引用时未调用finalize方法
  3. 为模块添加finalize方法的正确方法是什么

    (OS = Ubuntu,Julia Version = 0.4.0)

  4. 修改

    正如@Maciek所提到的,在gc()之后调用workspace()也没有帮助。

    感谢

1 个答案:

答案 0 :(得分:1)

恕我直言,workspace不接受囚犯,此外finalizer仅适用于用户定义和复合类型。

我已经完成了一些测试。看看我的结果:

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

在模块范围内定义了对象的另一个测试:

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

函数(第一类对象)怎么样?

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

总而言之:我认为workspace不会致电finalizefinalizer函数仅适用于用户定义和复合类型。它不适用于ModuleFunction

更新:我记得workspace将之前的Main模块重写为LastMain。因此,即使我们的模块不能从Main访问它,它仍然在LastMain范围内存活(对于我上面使用的函数也是如此)。