2015-10-25 17 views
6

私はジュリアのマニュアルを参照してくださいジュリアJuliaでモジュールファイナライズメソッドを書く正しい方法は何ですか?

ファイナライザを使用するための正しい方法を見つけるためにしようとしています:

ファイナライザ(X、機能)

は、関数fを登録(X)へのxへのプログラムアクセス可能な参照がないときに呼び出されます。 xがビット型の場合、この関数の動作は予測できません。

まず私はその後、私はパッケージをテストしようとしたが、一方で、私はERRORを受けTestModule.jl

#in TestModule.jl 
module TestModule 
end 
finalizer(TestModule,(t)->println("fin")) 

ともruntest.jl

#in runtest.jl 
using Base.Test 
using TestModule 

でTestModule標準パッケージをgenetatedテストをパスした:

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 

は、その後私はTestModuleこのようなfinalize方法を追加するテスト・プロセス中にエラーが発生なぜいくつかの質問

  1. を有する上記テストケースによれば、別のテストケース

    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 
    

    を配置しましたか? I明確な言及

  2. モジュール

    (OS = Ubuntuの、ジュリア・バージョン= 0.4.0)

ため finalize方法を追加するための正しい方法は何ですかながら finalizeメソッドが呼び出されなかったのはなぜ
  • @Maciekとして

    EDIT

    は役に立たない、またworkspace()gc()を呼び出し、言及しています。

    おかげ

  • 答えて

    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 finalizeを呼び出すことはありません。 finalizer関数は、ユーザー定義型および複合型に対してのみ有効です。 Moduleまたは Functionでは機能しません。

    更新:workspaceは、以前のMainモジュールをLastMainに書き換えることを思い出しました。したがって、私たちのモジュールがMainからアクセスできない場合でも、それはLastMainスコープ内にまだ生きています(私が上で使用した関数の場合も同じです)。