我正在编写一个单元测试框架,它将提供随机整数,布尔值,字符和字符串来测试函数。
Github回购:IoCheck。有问题的代码:
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
应生成0到99个元素的随机序列,使用生成器函数填充序列。出于某种原因,当genChar
通过时(请参阅genString
中的example.io
调用),genSeq
会在所有位置返回完全相同的元素。
答案 0 :(得分:2)
在调用之前评估您传递的参数genSeq
。
NB。与Python或Javascript之类的语言不同,括号不用于调用方法,而是在Io中用于向方法发送消息。因此gen
和gen()
是相同的,因为Io方法在使用时总是被调用。您可以使用getSlot
NB。此Hacker News评论的链接可能有所帮助:http://news.ycombinator.com/item?id=1539431
一种解决方案是传递block()
(匿名函数),然后从genSeq
内调用它:
genSeq := method (gen,
len := Random value(100) floor
0 to(len) map(i, gen call) // <= gen call ie. call the block
)
genString := method (
genSeq( block(genChar) ) join // <= wrapped in a block()
)
另一种方法是传递序列(字符串)并在其上运行perform
:
genSeq := method (gen,
len := Random value(100) floor
0 to(len) map(i, perform(gen)) // run string as method
)
genString := method (
genSeq( "genChar" ) join // method name is a sequence
)
另一种选择是懒惰评估论证:
genSeq := method ( // no defined parameters. Lazy time!
len := Random value(100) floor
0 to(len) map(i, call evalArgAt(0)) // <= arg is evaluated here!
)
genString := method (
genSeq( genChar ) join
)
顺便说一句......为了避免控制字符,我也做了这个改变(找不到Random
对象的文档,但下面是一个随机猜测,它有效!)。
genChar := method(
Random value(33, 128) floor asCharacter
)