如何创建 Str 的子类?

How do I create a subclass of Str?

我有这个 class,它基本上是 Str 属性的包装器:

use Vimwiki::File::TextProcessingClasses;
unit class Vimwiki::File::ContentStr;

has Str $!content;

submethod BUILD( :$content ) {
    $!content = $content;
}

method gist {
    return $!content;
}

method capitalize-headers() {
    $!content = Vimwiki::File::TextProcessingClasses::HeadlineCapitalizer.new.capitalize-headers($!content);
}

似乎用这样的东西来 subclass 核心 Str class 会更有效率,类似于我在 subclassing 中学到的技巧IO::Path:

class Blah is Str {
    method !SET-SELF() {
        self;
    }

    method new(Str:D $string) {
        self.Str::new($string)!SET-SELF();
    }    
}

my $blah = Blah.new('hello');
say $blah;

但是,这会引发错误:Default constructor for 'Blah' only takes named arguments

天哪,我胡乱猜测并通过 value 参数传递了 $string

class Blah is Str {
    method new(Str:D $string) {
        self.Str::new(value => $string);
    }    

    method whoa() {
        say self;
    }
}


my $blah = Blah.new('hello');
say $blah.flip;
$blah.whoa # it works!;

这有任何记录吗?

由于 Raku 中的构造函数是普通方法 - 至少如果编写正确 - 它们几乎可以工作,因此无需声明您自己的方法。子类化 Str 至少为:

class SubStr is Str {
}

我们可以验证它做正确的事情如下:

given SubStr.new(value => "hi") {
    say .WHAT;  # (SubStr) - correct type
   .say;        # hi - correct value
}

这似乎没有特别详细的记录。

另请注意,Str 是围绕“本机”str 的一个框,因此如果效率问题是关于内存消耗,那么您自己围绕 str 的框将消耗不超过 Str 本身。

unit class Vimwiki::File::ContentStr;
has str $!content;
...