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

bri*_*foy 7 subclass perl6

我如何继承IO :: Handle?例如,我想通过在每个之后调用flush来"autoflush" say:

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";
Run Code Online (Sandbox Code Playgroud)

但是,似乎MyIO从未被调用过.

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

所以,有些问题:

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

  • 由于它们的巫术和NQPness,内置类特别是对标准OO技术的抵抗吗?

  • Perl 6是否阻止使用句柄进行低级别的调整,例如在文件描述符上重新打开$*OUT?(如更改Perl 6的$*OUT更改子进程的标准输出?)

Eli*_*sen 11

Reblessing是sooo 90's :-)

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

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

这基本上创建了一个$*OUT基于现有的新动态,$*OUTsay混合了一个新方法.

尽可能回答你的问题:

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

say内部使用print,最好实际混合你自己的print方法:

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

这具有不再需要say作为方法调用的额外好处,因为子版本say$*OUT动态地拾取更改.