Как принудительно перезагрузить модуль?

Название говорит само за себя. Как при разработке модуля принудительно перезагрузить, чтобы протестировать новый код? Я могу переключаться с модуля на сценарий и создавать проблемы с привязкой и конфликты пространств имен, или я могу менять версию каждый раз, когда исправляю опечатку. Оба варианта плохие.

Я ищу что-то вроде import/force %my-module.reb для перезагрузки модуля в работающем сеансе (теперь мне нужно перезапустить R3, что не очень быстро для использования).


person rebolek    schedule 23.07.2014    source источник


Ответы (2)


Я не знаю, как вы импортируете свои модули, но если вы присвоите возвращаемое значение функции import переменной, повторное выполнение импорта загрузит новый код.

Например, у меня есть файл mod_a.reb:

REBOL []

forever [
    b: import %./mod_b.reb
    b/hello
    wait 10
]

и файл mod_b.reb:

REBOL []

hello: function [] [
    print "Hello"
]

Если вы запустите r3 ./mod_a.reb, вы увидите строку «Hello», которая печатается каждые 10 секунд. Если вы измените строку в mod_b.reb во время работы mod_a.reb, вы увидите другую строку.

person kronwiz    schedule 23.07.2014
comment
Я не назначаю модуль ничему, он экспортирует несколько функций, которые мне нужно использовать. Так же нужен еще один модуль (определен в шапке). Так что это немного другой случай, чем этот простой пример. - person rebolek; 29.07.2014

В настоящее время модуль не перезаписывает существующие значения (из соображений безопасности). Это работает так:

>> m: module [name: test][ export my-func: does[print "hello"]]
>> m/my-func
hello
>> my-func ;<- will error because module was not imported yet
** Script error: my-func has no value
>> import m
>> my-func ;<- now `my-func` is in user's but also `lib` contexts
hello
>> lib/my-func
hello

;-- one must unset it in both contexts
;-- and also remove module from list of existing modules

>> remove/part find system/modules 'test 3 unset 'my-func unset in lib 'my-func
>> import module [name: test][ export my-func: does[print "hello again"]]
>> my-func
hello again

Можно немного упростить, используя флаг private и version:

>> import module [name: test version: 1.0.0 options: [private]][export my-func: does[print "hello"]]
>> lib/my-func ;<- will error, because module is private
** Script error: cannot access my-func in path lib/my-func
>> my-func ;<- but it is still in user's context
hello
>> unset 'my-func
>> import module [name: test version: 1.0.1 options: [private]][export my-func: does[print "hello again"]]
>> my-func
hello again

Также можно написать функцию для выгрузки модуля (хотя она может работать не во всех случаях)

unload-module: function[module [word!]][
    m: system/modules/:module
    unless m [ exit ]
    e: select spec-of m 'exports
    forall e [
        print ["Unsetting:" e/1]
        try [unset in system/contexts/user e/1]
        try [unset in system/contexts/lib  e/1]
    ]
    remove/part find system/modules module 3
    m
]

; than:

>> import module [name: test][export my-func: does[print "hello"]]
>> my-func
hello
>> unload-module 'test
Unsetting: my-func
>> import module [name: test][export my-func: does[print "hello again"]]
>> my-func
hello again
person Oldes    schedule 17.12.2020