我有以下课程:
class Names {
has @!names;
method add-name( $name ) { @!names.push($name) }
multi method AT-POS( ::?CLASS:D: $index ) {
my $new-names-obj = Names.new;
for @!names[$index] -> $name {
$new-names-obj.add-name($name);
}
return $new-names-obj;
}
method gist {
@!names.join("\n")
}
}
我希望能够切片Names
对象和返回的值应该是另一个Names
对象,其元素与原始的Names
对象。例如:
my $original = Names.new;
$original.add-name($_) for <jonathan joseph jotaro josuke giorno>;
my $sliced-off = $original[0..2];
say $original.^name; #=> Names
say $original; #=> jonathan, joseph, jotaro, josuke, giorno
say $sliced-off.^name; #=> List
say $sliced-off; #=> (jonathan joseph jotaro)
[传递单个参数时,它按预期且按此answer中所述的方式工作,但范围不是这种情况,因为AT-POS
最终被多次调用并将结果收集在列表中。因此,我想知道使用范围时是否可以返回单个对象$sliced-off
,而不是结果列表。
基于Liz的指导:
class Names {
has @.names; # Make public so [] can access.
method new (*@names) { nextwith :@names } # Positional .new constructor.
submethod BUILD (:@!names) {} # Called by nextwith'd Mu new.
multi sub postcircumfix:<[ ]> # Overload [] subscript.
( Names $n, $index, *@indices ) # Why `$index, *@indices`?
is default is export # And why `is default`?
{ Names.new: |$n.names[ |$index, |@indices ] } # Why? See my comment
method gist { @!names.join(', ') } # below Liz's answer.
}
import Names;
my $original = Names.new: <jonathan joseph jotaro josuke giorno>;
my $sliced-off = $original[0..2];
say $original.^name; #=> Names
say $original; #=> jonathan, joseph, jotaro, josuke, giorno
say $sliced-off.^name; #=> Names
say $sliced-off; #=> jonathan, joseph, jotaro
如果代码或说明不足,请使用PLMK。
AT-POS
方法旨在让对象充当Positional
对象。这就是您想要的not。您需要object[slice]
DWIM。
实现此目标的最佳方法是为您的对象创建postcircumfic:<[ ]>
(多个)候选对象:
class A {
method slice(@_) {
say @_; # just to show the principle
}
}
sub postcircumfix:<[ ]>($object, *@indices) {
constant &slicer = &postcircumfix:<[ ]>;
$object ~~ A
?? $object.slice(@indices)
!! slicer($object, @indices)
}
A.new[1,2,4,5]; # [1 2 4 5]
my @a = ^10; # check if foo[] still works
say @a[1,2,4,5]; # (1 2 4 5)
[为了确保保留@a[]
的常规行为,我们在编译时保存系统postcircumfix:[ ]>
的值(使用constant
)。然后在运行时,当对象是正确类的not时,使用给定的参数调用postcircumfix:<[ ]>
的原始版本。