我如何继承 Perl 6 的 IO::Handle?

How could I subclass Perl 6's IO::Handle?

我如何继承 IO::Handle?例如,我希望能够通过在每个 say:

之后调用 flush 来 "autoflush"
class MyIO is IO::Handle {
    multi method say(MyIO:D: **@text --> True) {
        nextsame;
        $*ERR.say: "Flushing\n";
        self.flush;
        }
    };

Metamodel::Primitives.rebless: $*OUT, MyIO;
put $*OUT.^name;

$*OUT.say: "This is standard out";

但是,似乎从未调用过 MyIO。

我想我可能会换行 say 来产生效果,但我更感兴趣的是简单 sub类 覆盖某些行为的技术。但是,话虽如此,如果设计旨在让人们使用更多的 Perly 6 方式。

所以,一些问题:

祝福真是 90 年代 :-)

为什么不使用角色组合来实现您的目标?

role MyWay {
    method say(|) {
        note "whee";
        nextsame
    }
}
my $*OUT = PROCESS::<$OUT> but MyWay;
$*OUT.say("foo")   # whee\nfoo

这基本上是在现有 $*OUT 的基础上创建了一个新的动态 $*OUT,但混合了一种新方法 say

尽我所能回答您的问题:

  • 祝福被认为是你很可能不想做的内在事情
  • 很多内置的 类 通过不使用创建对象的标准方式来优化速度。这种排序使得很难对它们进行子类化。在某些情况下,特殊代码恢复为创建对象的标准方式,最终使这些 类 成为子类(如 Date)。
  • 通常我会说不建议低级别的摆弄,因为仍在进行内部重构以使事情变得更快,如果您摆弄得太低,这可能会破坏您的代码。

由于say内部使用了print,实际混入自己的print方法会更好:

role MyWay {
    method print(|) {
        note "whee";
        nextsame
    }
}
my $*OUT = PROCESS::<$OUT> but MyWay;
say "foo";   # whee\nfoo

这有一个额外的好处,就是不再需要调用 say 作为方法,因为 say 的子版本会动态地获取改变的 $*OUT