Хотя gather
/ take
спроектирован как полезная конструкция для отложенной обработки, он говорит всем, кто спрашивает, что он не является отложенным, независимо от того, содержит ли он бесконечное число. l oop:
say .is-lazy
for (gather { take 42 }), # False
(gather { loop { take 42 } }); # False
Итак, в вашем @f1 = gather ...
случае @f1
присваивается последовательность, которая говорит, что она не ленива, даже если она содержит бесконечное l oop. @
переменные sigil'd принимают это как сигнал для с нетерпением назначают последовательность - и код зависает.
Префикс lazy
создаст новый Seq
это будет лениво рисовать из выражения справа от него. Новый Seq
, созданный lazy
, сообщает миру, что it (новый Seq
) ленив:
say .is-lazy
for (lazy gather { take 42 }), # True
(lazy gather { loop { take 42 } }); # True
Если переменная @
sigil'd присваивается значение, которое возвращает True
для вызова .is-lazy
, тогда присваивание и переменная являются ленивыми. Так что код @f1 = lazy gather ...
работает отлично.
Наконец, последовательность (1...Inf)
знает , что это лениво, и говорит миру, что это без префикса lazy
:
say .is-lazy with (1 ... Inf) # True
Таким образом, назначение, которое также работает нормально, с или без lazy
.
Таким образом, переменная @
sigil'd получает элементы лениво, если назначено Seq
ему сказано, что это лениво, и с нетерпением жду иного.
Вы не спрашивали об этом, но другой сценарий - это присвоение или привязка Seq
к переменной $
sigil'd или идентификатор без сигилов.
Как и для переменной @
sigil'd, вызов .is-lazy
для переменной $
sigil'd или идентификатор без сигилов вернет True
или False
в соответствии с назначенный / связанный Seq
.
Но затем, независимо от того, от того, вернет ли .is-lazy
True
или False
, Seq
все равно будет повторяться лениво .