我有以下课程:
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")
}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够对一个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)
Run Code Online (Sandbox Code Playgroud)
当传递单个参数时,它会按预期工作并如本答案所述,但范围并非如此,因为AT-POS最终会被多次调用并将结果收集到列表中。因此,我想知道$sliced-off在使用范围时是否可以返回单个 object而不是结果列表。
该AT-POS方法旨在让对象充当Positional对象。这不是你想要的。你想要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)
Run Code Online (Sandbox Code Playgroud)
为了确保@a[]保留的常见行为,我们postcircumfix:[ ]>在编译时保存系统的值(使用constant)。然后在运行时,当对象不属于正确的类时,postcircumfix:<[ ]>使用给定的参数调用原始版本。
根据莉兹的指导:
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
Run Code Online (Sandbox Code Playgroud)
如果代码或解释不充分,请 PLMK。
| 归档时间: |
|
| 查看次数: |
104 次 |
| 最近记录: |