鬼鬼祟祟的参数

Sneaky Arguments

在玩 .WHY 的时候,我踏上了一个 ENODOC。方法指的是签名。两者都没有提到方法的默认签名。自动签名的文档中没有提到 %_ 总是被添加到方法中。询问 greppable6 是否提到了这一点,发现方法中 *%_ 有很多多余的用法。

my method m1(:$named) {}
my method m2(:$named, *%_) {}

say &m1.signature;
say &m2.signature;
# OUTPUT: (Mu: :$named, *%_)
          (Mu: :$named, *%_)

我之所以发现这个问题,是 .WHY。在 Raku 中,我们可以添加注释,这些注释附加在后面的语言对象上。

class Commented {
    #| this is an attribute
    has $.a-documented-attribute;
    #| this is a method
    method works {
        say ‚working as intended‘;
    }
}
say $c.^can('works')[0].WHY;
say $c.^attributes[0].WHY;
# OUTPUT: this is a method
          this is an attribute

文档中没有说明如何在运行时访问属性和方法的 WHY 节点。我们必须通过 MOP,因为方法和属性可以在运行时添加到类型对象中。至少对于方法,我找到了一个更好的方法来处理这个问题。

method works {
    return &?ROUTINE.WHY if %_;
    say ‚working as intended‘;
}
put $c.works(:why);

奇怪的是,这就导致了一个尴尬的情况,那就是我给一个方法添加了一个没有文档的参数,而这个参数会返回该方法的文档。明确地说,我们得到了 trait is implementation-detail。不过被迫使用 multi,让事情变得更加麻烦。

#| No comment! We are sneaky!
multi method sneaky { say ‚working as intended‘ }
multi method sneaky('why') is implementation-detail {
    return self.^lookup('sneaky').candidates[0].WHY;
}
say $c.sneaky('why');

这就有一个问题,为什么我需要属性上的 .WHY。我确实同意 JSON 总体上缺乏的评估。我最大的反对是缺乏注释。对于配置文件来说,能够告诉同事不要让他的手指沾到某一行的脏东西,可以拯救生命。Debian 也很好地利用了这些文件中的注释。如果你不需要为了改变一个值而阅读一个手册页的话,就可以节省很多时间。通过对属性的内联注释,我可以同时表达配置文件中存储的数据结构和如何使用配置文件的说明,而不需要另一个与实际代码不同步的 HEREDOC。我很喜欢 NestedText 的结构,正在玩添加类型信息。在 NestedText 中,叶子默认为 Str,所以可以省略。在 Raku 中,我们可以免费获得类型的字符串表示,我们可以直接将它们作为文本添加。

我可以定义我的配置文件的结构如下。

use Data::TypedNestedText;

class Phone {
    has $.mobile;
    has $.home;
    has $.office;
}

class Contact {
    has $.name;
    #| this can be multiline
    has $.address;
    has $.phone;
    has @.additional-roles;
}

对于输出,我写了一个天真的 deparser,可以产生一个带有类型注释的 NestedText。

president[Contact]:
    # this can be multiline
    address:
        > 138 Almond Street
        > Topika, Kansas 20697
    name: Katheryn McDaniel
    phone[Phone]:
        home: 1-210-555-8470
        mobile: 1-210-555-5297
treasurer[Contact]:
    # this can be multiline
    address:
        > 3636 Buffalo Ave
        > Topika, Kansas 20692
    name: Fumiko Purvis
    phone[Phone]:
        office: 1-268-555-0280
    additional-roles:
        - hug task force
        - Christmas party team

这比 JSON 更容易阅读和编辑。编写解析可能不容易。如果事实证明它比预期的更容易,我将很快报告。

原文链接: https://gfldex.wordpress.com/2020/10/10/sneaky-arguments/

comments powered by Disqus