我怎样才能将Perl 6的IO :: Handle子类化?

时间:2017-07-11 02:50:52

标签: subclass perl6

我如何将IO :: Handle子类化?例如,我希望能够" autoflush"通过在每say之后调用flush:

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从未被调用过。

我认为我可能会说要产生效果,但我对简单子类的技术更有兴趣来覆盖某些行为。但是,话虽如此,如果有更多的Perly 6方式,设计意图供人们使用。

所以,有些问题:

  • Perl 6是否非常谨慎地关注它?它如何查找可能跳过该方法名称的方法名称?

  • 内置类是否因为它们的巫术和NQP而特别抵抗标准的OO技术?

  • Perl 6是否阻止使用句柄进行低级别的摆弄,例如在文件描述符上重新打开$ * OUT? (如Does changing Perl 6's $*OUT change standard output for child processes?

1 个答案:

答案 0 :(得分:11)

Reblessing is sooo 90&s: - )

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

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

这基本上会根据现有$*OUT创建一个新动态$*OUT,但会混合使用新方法say

尽我所能回答你的问题:

  • reblessing被认为是你很可能不想做的内部事情
  • 许多内置类通过不使用标准创建对象的方式来优化速度。这种分类很难对它们进行子类化。在某些情况下,特殊代码会恢复为制作对象的标准方式,使这些类毕竟是可子类化的(如Date)。
  • 一般情况下我会说低级别的小提琴不建议,因为仍有内部重构正在进行以使事情变得更快,如果你的调整过低,可能会破坏你的代码。

由于say内部使用print,因此最好实际混合使用您自己的print方法:

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

这样做的另一个好处就是不再需要调用say作为方法,因为say的子版本会动态地获取已更改的$*OUT