Implementing AT-POS to return an object instead of a list of things
我有以下课程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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("\ ") } } |
我希望能够切片
应该是另一个
原始的
1 2 3 4 5 6 7 8 | 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) |
当传递单个参数时,它按预期且如此答案中所述工作,但范围不是这种情况,因为
实现此目标的最佳方法是为对象创建
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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) |
为确保保留
基于Liz的指导:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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。