Аргумент, который вы передаете 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
)