Ошибка случайного значения в Io - PullRequest
2 голосов
/ 12 октября 2011

Я пишу каркас модульного теста, который будет предоставлять случайные целые числа, логические значения, символы и строки для тестирования функций.

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 возвращает одинаковый элемент во всех позициях.

1 Ответ

2 голосов
/ 12 октября 2011

Аргумент, который вы передаете genSeq, оценивается перед его вызовом.

Примечание.В отличие от языков, таких как 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
)
...