导出动态范围的变量?

时间:2018-11-15 19:22:46

标签: perl6

基本上,问题更多是关于语法,但我认为这可能是关于动态变量的更有趣的练习。

我有一个带有原型标记的语法角色(示例被简化以演示该思想):

proto token foo {*}
token foo:sym<a> {
   :my $*delimiter = q<">;
   \" ~ \" <value>
}
token foo:sym<b> {
   :my $*delimiter = q<'>;
   \' ~ \' <value>
}
token value {
    .+? <?before $($*delimeter) || $($*custom-delimiter)>
}

当角色被语法占用时,我希望$*custom-delimiter由语法设置。当然,我可以在需要<foo>的任何地方声明它。但是有时可以使用通用默认值对其进行预初始化。像这样:

{ $*custom-delimiter //= $default-delimiter }
value令牌中的

将起作用。但是仍然需要外部预先声明。

我希望:

our $*custom-delimiter is export = $default-delimiter;
在声明角色的模块范围内

可以工作。但显然不是。因此,问题是:对此是否有任何优雅的解决方案?

实际上,我还希望该解决方案也允许将$*delimiterfoo的声明也移到令牌定义之外。

作为旁注:我的第一个想法是关于向令牌添加参数。但是,每个变体具有完全相同的签名看起来也很糟糕:

token foo:sym<a> ( $*custom-delimiter = $default-delimiter ) {
}
token foo:sym<b> ( $*custom-delimiter = $default-delimiter ) {
}
token foo:sym<c> ( $*custom-delimiter = $default-delimiter ) {
}

另一种方法是使用类似的东西

token pre-foo ( $*custom-delimiter = $default-delimiter ) {
    <foo>
}

在这种情况下,动作类将需要一个附加方法来将$/<foo>.ast传播到一个更高的级别。

1 个答案:

答案 0 :(得分:1)

基于我在一个模块中所做的一些测试工作,以允许对模块进行范围设置,您可以执行此操作,但是您将需要使用EXPORT子项。

我想原因是在执行EXPORT时,我们可以显式地安装一个全新的动态变量,而不是链接到一个现存的动态变量的新符号-对我而言,后者使作用域非常不清楚。

这对我来说似乎还可以。

# filename: Foo.rakumod
# no 'unit module', etc

sub EXPORT {
  proto token foo {*}
  token foo:a { … }
  token foo:b { … }

  Map.new: 
    '&foo'      => &foo,
    '$*dynamic' => my $ = 'default'
}