Как правильно написать метод финализации модуля в Юлии?

Я пытаюсь найти правильный способ использовать финализаторы в Юлии

Обратитесь к документации Юлии:

финализатор (х, функция)

Зарегистрируйте функцию f(x), которая будет вызываться при отсутствии доступных для программы ссылок на x. Поведение этой функции непредсказуемо, если x имеет битовый тип.

Сначала я создал стандартный пакет TestModule с помощью TestModule.jl

#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 

По приведенным выше тестам у меня есть несколько вопросов

  1. Зачем добавлять такие finalize метод для TestModule генерирует ОШИБКУ во время процесса тестирования?
  2. Зачем finalize метод не был вызван, пока я очищаю ссылки
  3. Как правильно добавить finalize метод для модуля

    (OS=Ubuntu, версия Julia =0.4.0)

РЕДАКТИРОВАТЬ

как упомянул @Maciek gc() после workspace() Кроме того, не помогают.

Спасибо

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 область действия (то же самое работает для функции, которую я использовал выше).

Другие вопросы по тегам