Preparations for Your

楽土

在他出色的演讲中,Damian Conway 展示了如何实现一个新的声明符,他把这个声明符称为 your,它会把任何值的变化输出到容器中进行调试。整件事让我担心 Perl 5 可能会超越 Perl 6,导致更多的命名混乱,因为我们已经得到了。所以我又开始让我们领先一点。

我们还不能在 Perl 6 中轻易地实现声明符,但花哨的容器是没有问题的。我们需要的只是一个能进行类型检查的 Proxy。后者可以通过在构造函数中进行类型捕获来实现。

class Watched {
    has Mu $.container is rw;
    my $quote-start = '⟨';
    my $quote-end = '⟩';

    method new(::T, :$name = '<unnamed>') {
        my $self = self.bless(:container(T));
        Proxy.new(
            FETCH => method () { $self.container },
            STORE => method (T $new-value) {
                temp $quote-start;
                temp $quote-end;
                if $*ERR.t {
                    $quote-start := "\e[7m";
                    $quote-end := "\e[0m";
                }
                note "Container $name changed from {$quote-start ~ $self.container.gist ~ $quote-end} to {$quote-start ~ $new-value ~ $quote-end}";
                $self.container = $new-value
            }
        )
    }
}

获取容器棒我们需要使用绑定。遗憾的是,如果没有适当的宏支持,就无法自动获得容器名称,因为 Proxy 不支持与 Scalar 相同的接口。另一方面,手动提供它可以提供更多的灵活性。

my $c := Watched.new(Int, :name<$c>);

dd $c; # Int
$c = 42; # STDERR: Container $c changed from (Int) to 42
dd $c; # 42

我希望已经证明了在 Perl 5 和 Perl 6 中,多一个层次的间接性也同样有效。

更新:如果我们输出到 STDERR,我们最好测试一下 $*ERR 是否是一个 tty。

by gfldex

comments powered by Disqus