How do I force module reload? - module

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

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.

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

Related

How can I compile a script that has some dynamic code?

I want to compile this script:
Red [File: %b.red]
context [
a: 123
hidden: 999
set 'global-exports context [
export-a: a
]
]
probe global-exports
But I get an error when trying to compile it with $ ./red-13oct19-a4ee537c -r b.red:
*** Red Compiler Internal Error: Script Error : Invalid path value: global-exports
*** Where: register-object
*** Near: [objects/context/global-exports: make object! [
a: none
hidden: none
]]
In general, you can wrap dynamic code with do [...] function, which treats a block of code like data and uses an interpreter to launch it at runtime:
Red [File: %b.red]
context [
a: 123
hidden: 999
do [ ;-- the code inside is run by interpreter at runtime
set 'global-exports context [
export-a: a
]
]
]
probe get 'global-exports ;-- dynamic retrieval
You also have to retrieve values dynamically, unless you initialize it statically (e.g. global-exports: none) somewhere earlier.
In this particular case also exchanging context with make object! will be sufficient:
Red [File: %b.red]
context [
a: 123
hidden: 999
set 'global-exports make object! [
export-a: a
]
]
probe global-exports
Compiling dynamic code will be possible with JIT compiler, which is planned in future, but not before Red version 1.0.
(thanks #9214 and #hiiamboris for the ideas on red/help gitter chat)

How can I test that an imported Perl 6 routine exists?

I want to check that an exportable subroutine isn't defined in the current scope, and I also want to test that a subroutine isn't defined. Both of these should happen without running the code and I'd really like a way to do it without an EVAL. The examples I found in the roast executed the subroutines that the testers assumed were already there.
Here's what I cobbled together, but it's mostly unsatisfying for a language where I expect to be able to inspect things:
use Test;
module Foo {
sub this-exists is export { say "This exists"; return 1 }
sub this-is-a-stub is export { !!! }
sub this-is-a-todo is export { ... }
sub not-exported { say "Not exported" }
}
import Foo; # https://github.com/perl6/doc/issues/359
# Is the class there?
ok ::("Foo") !~~ Failure, "module Foo is defined";
ok ::("Bar") ~~ Failure, "module Bar is not defined";
# this should work, but note the first one compiles because it works.
# if the routine isn't there, the &some-name is a compilation error.
ok &this-exists, "this-exists is there";
ok &("not-there"), "this-exists is there";
# these are exported but they aren't "defined" because they
# are stubs. How is this supposed to work?
dies-ok { EVAL Q/&this-is-a-stub/ }, "this-is-a-stub is not defined";
nok &("this-is-a-stub"), "this-is-a-stub is not defined";
nok &("this-is-a-todo"), "this-is-a-todo is not defined";
# these shouldn't be defined here
dies-ok { EVAL Q/ &not-exported / }, "not-exported is not defined";
dies-ok { EVAL Q/ &not-there / }, "not-there is not defined";
done-testing();
say so ::('&non-existent'); # False
say so ::('&say'); # True
if ::('&say') -> &say {
say 4; # 4␤
}
Note that these also work to reference a subroutine that may or may not exist.
&::('say')
::{'&say','&put'}
::<&say &put> # similar to previous line
&CORE::('say')
CORE::('&say')
CORE::{'&say','&put'}
CORE::<&say &put> # similar to previous line
Also &(…) is for coercing something to a code type object, so only works on things that are already a Callable or have a CALL-ME method.

How can I call a subprocess in Idris?

Is there some module in the Idris standard library (or a third party library) that allows one to shell out to another program? I'm thinking of modules like Python's subprocess and Haskell's System.Process.
Ideally, I'd like to interact programmatically with the process (writing to its stdin, reading from its stdout, etc.).
There is the system : String -> IO Int function which takes a shell command, runs it, and returns its exit code. You'll need to import System to use it:
import System
main : IO ()
main = do
exitCode <- system "echo HelloWorld!"
putStrLn $ "Exit code: " ++ show exitCode
exitCode <- system "echo HelloWorld!; false"
putStrLn $ "Exit code: " ++ show exitCode
On my system the above code results in the following output:
HelloWorld!
Exit code: 0
HelloWorld!
Exit code: 256
I'd expect it to return 1 instead of 256 in the second case. At least it's what echo $? shows.
Another version can be made basing on the Effects library, which is described in this tutorial:
import Effects
import Effect.System
import Effect.StdIO
execAndPrint : (cmd : String) -> Eff () [STDIO, SYSTEM]
execAndPrint cmd = do
exitCode <- system cmd
putStrLn $ "Exit code: " ++ show exitCode
script : Eff () [STDIO, SYSTEM]
script = do
execAndPrint "echo HelloWorld!"
execAndPrint "sh -c \"echo HelloWorld!; exit 1\""
main : IO ()
main = run script
Here we need to explain to Idris that it needs the Effects package:
idris -p effects <filename.idr>
I'm not aware of any Idris library that lets you easily work with stdin/stdout of a subprocess. As a workaround we can use the pipes facilities of C, utilizing its popen / pclose functions, which aready have bindings in the Idris standard library.
Let me show how we could, for example, read from stdout of a subprocess (please bear in mind that it's a simple snippet with rudimentary error processing):
import System
-- read the contents of a file
readFileH : (fileHandle : File) -> IO String
readFileH h = loop ""
where
loop acc = do
if !(fEOF h) then pure acc
else do
Right l <- fGetLine h | Left err => pure acc
loop (acc ++ l)
execAndReadOutput : (cmd : String) -> IO String
execAndReadOutput cmd = do
Right fh <- popen cmd Read | Left err => pure ""
contents <- readFileH fh
pclose fh
pure contents
main : IO ()
main = do
out <- (execAndReadOutput "echo \"Captured output\"")
putStrLn "Here is what we got:"
putStr out
When you run the program, you should see
Here is what we got:
Captured output

Is there an assertException in any of the Haskell test frameworks?

I'm writing some tests using HUnit and I would like to assert that a particular function throws an exception given a certain input. I can't find an assert function which provides the required functionality. Anyone know of a test framework that does?
Although HUnit doesn't come with any exception assertions, it's easy to write your own:
import Control.Exception
import Control.Monad
import Test.HUnit
assertException :: (Exception e, Eq e) => e -> IO a -> IO ()
assertException ex action =
handleJust isWanted (const $ return ()) $ do
action
assertFailure $ "Expected exception: " ++ show ex
where isWanted = guard . (== ex)
testPasses = TestCase $ assertException DivideByZero (evaluate $ 5 `div` 0)
testFails = TestCase $ assertException DivideByZero (evaluate $ 5 `div` 1)
main = runTestTT $ TestList [ testPasses, testFails ]
You can do something more fancy like using a predicate instead of explicit comparison if you like.
$ ./testex
### Failure in: 1
Expected exception: divide by zero
Cases: 2 Tried: 2 Errors: 0 Failures: 1
Note that evaluate here might get optimized away (see GHC ticket #5129), but for testing code in the IO monad this should work fine.
You can use assertRaises from testpack.
hspec (or more precisely hspec-expectations) has shouldThrow.

Programming a sandbox environment in rebol a bit like spoon.net

http://spoon.net let's you execute desktop application by downloading them from the web. When you quit it restores the system.
On http://askpoweruser.com I'd like to do the same thing. My idea would be to persist the whole system hierarchy on disk and then restore it at the end of execution.
Is a single line of code would be enough (seems like too easy for such complex feature that's why I doubt :)):
save %system.txt system
what is serialize refinement ? would it be usefull in that case ?
to restore system would I then just do
load %system.txt
here is my object:
>> o: context [b: "b" f: does [do make function! [] [print ["a"]]] oo: context [a: 1]]
>> ?? o
== o: make object! [
b: "b"
f: func [][do make function! [] [print ["a"]]]
oo: make object! [
a: 1
]
]
change something in function f:
>> o/oo/a: 2
>> append second last second first next next next third :o "b"
>> o/f
== a b
>> save/all %t.r :o
>> p: load %t.r
>> ?? p
== p: make object! [
b: "b"
f: func [][do make function! [] [print ["a" "b"]]] ;<----
oo: make object! [
a: 2 ;<------
]
]
>> p/f
== a b ;<----
it looks everything is ok. But of course this is just a single test.
You can't currently save the entire Rebol image like this. You can serialize Rebol values by using 'mold/all and save values by using 'save. But AFAIK the serialization doesn't properly save functions inside objects.
You could use something like CryoPID:
http://cryopid.berlios.de/
That would work at the process level, and you could use it for things besides Rebol. But it would be OS-specific.