Я пытаюсь создать итератор, а затем построить последовательность из него, но он не действует так, как мне кажется. Что случилось?
Вот мой основной класс:
class Foo {
has $.x = 0;
has $.max = 3;
method val() {
(++$!x > $!max) ?? () !! ($!x, "string $!x")
}
}
my $foo = Foo.new;
say $foo.val.perl for ^4;
# (1, "string 1")
# (2, "string 2")
# (3, "string 3")
# ()
Он просто повторяется до max, затем возвращает (), работает так, как я думаю.
Затем я создаю из этого итератор, всего один pull-one()
метод.
class Foo-Iterator does Iterator {
has Foo $.foo;
method pull-one() {
$!foo.val || IterationEnd
}
}
my $iter = Foo-Iterator.new(foo => Foo.new);
$iter.pull-one.perl.say for ^4;
# (1, "string 1")
# (2, "string 2")
# (3, "string 3")
# IterationEnd
Это все еще действует так, как я ожидаю.
Если я обращаюсь к нему с помощью Seq, он все равно работает нормально:
.perl.say for Seq.new: Foo-Iterator.new(foo => Foo.new);
# (1, "string 1")
# (2, "string 2")
# (3, "string 3")
Это все еще то, что я ожидаю увидеть, то же самое, что вернул Итератор.
Наконец, я сохраняю Seq в переменной @
и печатаю результаты этого:
my @seq = Seq.new: Foo-Iterator.new(foo => Foo.new);
.perl.say for @seq;
# $(4, "string 1")
# $(4, "string 2")
# $(4, "string 3")
Что с этим? Похоже, что он использует более позднее значение переменной, а не значение, которое она имела во время вызова pull-one () (которое в строке выдает значение). Seq
возвращает его как контейнер, а не значение? Это лень в действии, когда он не тянет до тех пор, пока не будет запрошено, чтобы получить более позднее значение?
Если я заставлю val()
вернуть +$!x
вместо возврата $!x
, мне кажется, что оно берет значение и дает мне то, что я хочу, я просто пытаюсь понять поведение, которое вижу.