在 #perl6 上,jnthn provided several approaches。他们中的一些人并没有像我期望的那样行事。
我按照以下方式更新了课程
jjmerelo's suggestion:
class Word-Char does Iterable does Iterator {
has @.words;
has Int $!index = 0;
method !pairize($item) {
return $item => $item.chars;
}
method iterator() {self}
method pull-one( --> Mu ) {
if $!index < @!words.elems {
my $item = @!words[$!index];
$!index += 1;
return self!pairize($item);
}
else {
return IterationEnd;
}
}
}
1。将对象绑定到位置
# Binding to a Positional
my @w01 := Word-Char.new: words => <the sky is blue>;
这会产生以下错误:
Type check failed in binding; expected Positional but got Word-Char...
2。在迭代点使用|
my $w = Word-Char.new: words => <the sky is blue>;
for |$w {
.say
}
=begin comment
Word-Char.new(words => ["the", "sky", "is", "blue"])
=end comment
| 对似乎保持其标量性质的对象没有影响,因此for 不会对其进行迭代。
3。使用无符号变量
my \w = Word-Char.new: words => <the sky is blue>;
for w {
.say
}
=begin comment
he => 3
sky => 3
is => 2
blue => 4
=end comment
到目前为止,这是符合我期望的最干净的方法。
4。与其让类可迭代,不如添加一个返回可迭代内容的方法。
事实上,这是我的第一个方法,但我没有发现它太p6y。无论如何,要让它工作,我们需要更新我们的类并添加一个返回可迭代内容的方法。我选择的方法名称是LOOP-OVER,如果只是为了让它从其他东西中脱颖而出。
class Word-Char {
has @.words;
method !pairize($item) {
return $item => $item.chars;
}
method LOOP-OVER {
gather for @!words -> $word {
take self!pairize($word)
}
}
}
my $w = Word-Char.new: words => <the sky is blue>;
for $w.LOOP-OVER {
.say
}
=begin comment
he => 3
sky => 3
is => 2
blue => 4
=end comment
但是,如果我们依赖多个迭代行为的类怎么办?我们如何确保它们实现相同的方法?最直接的方法
在这种情况下,是组成一个角色(例如,Iterationable),它实现了一个存根 LOOP-OVER 方法。
role Iterationable {
method LOOP-OVER { ... }
}
class Word-Char does Iterationable {
has @.words;
method !pairize($item) {
return $item => $item.chars;
}
method LOOP-OVER {
gather for @!words -> $word {
take self!pairize($word)
}
}
}
class Names does Iterationable {
has @.names;
method LOOP-OVER {
gather for @!names -> $name {
take $name.split(/\s+/)».tc.join(' ')
}
}
}
class NotIterable {
has @.items
}
my @objs =
Word-Char.new(words => <the sky is blue>),
Names.new(names => ['Jose arat', 'elva delorean', 'alphonse romer']),
NotIterable.new(items => [5, 'five', 'cinco', 'cinq'])
;
for @objs -> $obj {
if $obj.can('LOOP-OVER') {
put "» From {$obj.^name}: ";
for $obj.LOOP-OVER {
.say
}
}
else {
put "» From {$obj.^name}: Cannot iterate over it";
}
}
=begin comment
» From Word-Char:
the => 3
sky => 3
is => 2
blue => 4
» From Names:
Jose Arat
Elva Delorean
Alphonse Romer
» From NotIterable: Cannot iterate over it
=end comment
正如jnthn 所述,使用哪种方法(至少来自工作方法)几乎不取决于手头的问题。