【问题标题】:Is it possible to make compile-time code non-cached in Perl 6?是否可以在 Perl 6 中使编译时代码不缓存?
【发布时间】:2019-01-06 21:54:00
【问题描述】:

假设我想在编译时创建一些类型,但在此之前,让我们用一个更简单的例子来测试编译时代码:

# in file root.pm6
sub foo($a) { $a.say }

sub EXPORT {
    # Things here may be a lot more complex
    foo 1;
    foo 2;
    foo 1;
    %( one => 1 )
}

以及直接原始库和最终用户文件之间的模块:

# in file middle.pm6
use root;
class A {} # Do something with stuff from root.pm6

最终用户文件:

# in file user.pm6
use middle;

然后在命令行中:

➜  tester perl6 -I. user.pm6
1
2

似乎对foo 的第三次调用已被缓存,第三次没有执行。

这种行为使得sub EXPORT(以及其他编译时区域)中任何相对复杂的计算(基于代码重用)变得不可能。

根据我的理解,编译时代码意味着正常执行,其结果(例如一些声明、调整等)可由其他模块从编译单元访问。但是,也涉及到某种缓存。

问题最终是“如何实现我想要的”以及可能的里程碑:

1)这种缓存是有意的吗?

2)如果是,是否可以在具有编译时代码执行优势的同时禁用它?如果不是,还有哪些可能的解决方法?

更新 1:更具体地解释我想要的东西:在编译时,我正在解析一个配置文件并创建要导出的类型。我希望那些被预编译,这就是重点。类型可以嵌套并且各种情况都是可能的,所以我提交了一个过渡状态机模拟,它实现为一个简单的子例程,带有很长的given-where 语句,一些分支是递归的(底部总是存在的)。我坚持的问题是某些分支在被解雇一次后不会被执行,我可以打出简单的双 foo 1 电话我在主要问题中提出。

更新 2:如 raiph 所述,当原始库和用户一之间的间接级别为 0 时,从命令行运行时它可以正常工作,但当结构为 root lib file that creates types -> middleware lib file that patches those -> end-user(be it a test file or another module 时,并非所有代码都被执行。

【问题讨论】:

  • 我只阅读了你的问题的标题而不是它的正文。所以这可能没用,但你见过no precompilation;吗?另请参阅Constants are computed at compile time
  • 至于那两个: 1) 事实上,我想要 东西被预编译,这是我工作的重点。 2)至于常量 - 是的,但我不确定它是否相关。
  • @Takao 我看不出“预编译”和“缓存”之间的区别。预编译在(默认).precomp 目录中创建一个预编译缓存。如果你想测试编译它们,你可以使用 perl6 -c,但这也意味着预编译。也许您应该考虑使用不同的移相器而不是 EXPORT,尽管我知道您希望导出变量,但是有不同的方法可以实现。
  • 我刚刚在 REPL 之外尝试了您的代码并得到了1␤2␤1␤,即它按我的预期工作。
  • 确实如此。但是,当间接级别超过 2(即 lib -> lib -> lib)时,它不会像这样工作,第一个使用预编译。我会更新问题。

标签: raku


【解决方案1】:

这似乎是一个 Rakudo 错误或与它足够接近的东西。

至少,正如 Jonathan Worthington 所建议的那样,使用 note 而不是 say 可以使示例代码在必要时工作,这消除了对可能涉及的缓存的所有影响。

【讨论】:

    【解决方案2】:

    也许您正在查看INIT 移相器:

    INIT {
        # Things here may be a lot more complex
        foo 1;
        foo 2;
        foo 1;
        %( one => 1 ) 
    }
    

    这对你来说可能有点过于冗长:

    > use user;
    1
    2
    1
    2
    1
    

    INITis run at runtime。如果您想为变量赋值,它将完成工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-14
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-28
      • 1970-01-01
      • 2012-05-12
      相关资源
      最近更新 更多