I'm writing a unit test framework that will supply random integers, booleans, characters, and strings to test functions.
Github repo: IoCheck. Code in question:
genChar := method(
Random value(128) floor asCharacter
)
genSeq := method(gen,
len := Random value(100) floor
0 to(len) map(i,
gen()
)
)
genString := method(
genSeq(genChar) join
)
# below always has same genChar
"Random string: #{genString}" interpolate println
genSeq
should generate a random sequence of 0 to 99 elements, using a generator function to populate the sequence. For some reason, when genChar
is passed (see the genString
call in example.io
), genSeq
returns the exact same element in all positions.
The argument you pass
genSeq
is evaluated before calling it.NB. Unlike languages like Python or Javascript, parenthesis aren't used to call the method and instead in Io its used to send messages to the method. Thus
gen
andgen()
are the same because in Io methods are always called when used. You can access the method without calling it by usinggetSlot
NB. This link to a comment on Hacker News may help: http://news.ycombinator.com/item?id=1539431
One solution is to pass a
block()
(anonymous function) instead and then call it from withingenSeq
:Another alternative is to pass a sequence (string) and run
perform
on it:And another alternative is to lazy evaluate the argument:
BTW... to avoid control characters I also did this change (couldn't find doc for
Random
object but below was a random guess and it worked!).