2

我正在编写一个单元测试框架,它将提供随机整数、布尔值、字符和字符串来测试函数。

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 个元素的随机序列,使用生成器函数来填充序列。出于某种原因,whengenChar被传递(参见 中的genString调用example.io),genSeq在所有位置返回完全相同的元素。

4

1 回答 1

2

您传递的参数genSeq在调用它之前被评估。

注意。与 Python 或 Javascript 等语言不同,括号不用于调用方法,而是在 Io 中用于向方法发送消息。因此gengen()是相同的,因为在 Io 中方法总是在使用时被调用。您可以访问该方法而无需通过使用调用它getSlot

注意。这个指向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
)
于 2011-10-12T09:34:09.840 回答