rebolek
rebolek

Reputation: 1301

How do I force module reload?

The title says it all. When developing a module, how do I force reload, to test new code? I can switch from module to script and introduce binding problems and namespace conflicts, or I can change the version every time I fix a typo. Both are bad options.

What I'm looking for is something like import/force %my-module.reb to reload the module in running session (now I have to restart R3 which is not very fast pattern to use).

Upvotes: 1

Views: 173

Answers (2)

Oldes
Oldes

Reputation: 989

Currently module does not overwrite existing values (for security reasons). It works like:

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

One can simplify it a little bit using private flag and 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

It's also possible to write a function for module unloading (although it may not work in all cases)

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

Upvotes: 1

kronwiz
kronwiz

Reputation: 193

I don't know how you're importing your modules, but if you assign the return value of the import function to a variable re-executing the import loads the new code.

For example I have the file mod_a.reb:

REBOL []

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

and the file mod_b.reb:

REBOL []

hello: function [] [
    print "Hello"
]

If you run r3 ./mod_a.reb you see the "Hello" string printed every 10 seconds. If you modify the string in mod_b.reb while mod_a.reb is running you see a different string printed.

Upvotes: 1

Related Questions