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

在Julia中编写模块finalize方法的正确方法是什么?,julia,Julia,我正在努力找到在Julia中使用终结器的正确方法 请参阅以下文档: 终结器(x,函数) 注册一个函数f(x),当没有程序可访问的x引用时调用该函数。如果x是位类型,则此函数的行为是不可预测的 首先,我用TestModule.jl生成了一个TestModule标准包 #in TestModule.jl module TestModule end finalizer(TestModule,(t)->println("fin")) 还有一个runtest.jl #in ru

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

请参阅以下文档:

终结器(x,函数)

注册一个函数f(x),当没有程序可访问的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
然后我尝试测试包,但在测试通过时收到错误:

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 
根据以上测试案例,我有一些问题

  • 为什么为
    TestModule
    添加这样的
    finalize
    方法会在测试过程中产生错误

  • 为什么在清除引用时未调用
    finalize
    方法

  • 为模块添加
    finalize
    方法的正确方法是什么

    (OS=Ubuntu,Julia版本=0.4.0)

  • 编辑

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


    感谢

    IMHO,
    工作区
    不受约束,此外,
    终结器
    仅在用户定义和复合类型上工作良好

    我做了一些测试。看看我的结果:

    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")
    
    函数(一级对象)呢

    因此,总结一下:在我看来,
    workspace
    不调用
    finalize
    finalizer
    函数仅对用户定义的和复合类型有效。它不适用于
    模块
    功能

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

    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