但是,当我在程序文本中出错时,我无法阅读文档时感到很惊讶.这里我省略了两个语句之间的语句分隔符:
use v6; BEGIN { put "BEGIN" } INIT { put "INIT" } CHECK { put "CHECK" } "foo" "bar"; DOC INIT { put "DOC INIT" } DOC BEGIN { put "DOC BEGIN" } DOC CHECK { put "DOC CHECK" } =begin pod =head1 This is a title This is a bit of pod =end pod
当我使用–doc开关运行它时,程序语法很重要(并且BEGIN运行):
$perl6 --doc doc.p6 BEGIN ===SORRY!=== Error while compiling ... Two terms in a row ------> "foo"⏏ "bar"; expecting any of: infix infix stopper statement end statement modifier statement modifier loop
当我修复它时,我得到一些警告(因此,perl6正在编译)并且编译时阶段运行程序运行:
BEGIN DOC BEGIN DOC CHECK CHECK WARNINGS for /Users/brian/Desktop/doc.p6: Useless use of constant string "bar" in sink context (line 9) Useless use of constant string "foo" in sink context (line 9) INIT DOC INIT This is a title This is a bit of pod
我们已经知道这在Perl 5中有点危险.perl -c和BEGIN块可以运行代码.见How to check if a Perl script doesn’t have any compilation errors?.我认为这不比我们已经知道的更危险,但现在它发生在我没有明确要求编译程序语句的时候.
我没有深入研究Perl 6 pod的细节以及为什么在声明器块和.WHY(一个很酷的功能)之外可能需要它,但似乎这会导致麻烦.是否有可能提取Pod的外部程序?或者除非程序运行,否则没有声明器的方法?
解决方法
Perl 6语言设计用于从上到下的一次解析,因此在任何给定的点上,解析器根据它到目前为止解析的内容来理解解析的内容.
考虑以下代码:
say " =begin pod Not POD,just a string! ";
如果您只是为POD语句grep文件而不解析所有这些,它会误解这段代码.
即你不能解析POD部分而不解析普通的Perl 6代码部分,因为如果不从上到下解析它,你就不知道哪个是哪个.
PS:从理论上讲,Perl 6设计人员可以通过使普通的Perl 6代码包含看起来像是启动POD块的行是非法的,仅适用于POD解析.在这种情况下,解析整个文件时上面的代码片段会出现语法错误,因为不允许在带有= begin pod的字符串文字中开始一行,所以–pod开关可以依赖所有以=开始foo实际启动POD块.
这样的限制可能不会成为普通Perl 6代码的主要负担(毕竟,谁需要在多行字符串文字的行开头写=开始pod),但请注意其中一个原因一次通过从上到下的解析架构是为了通过俚语促进语言的可扩展性.
例如. CPAN模块可以为用户在另一种语言或DSL中编写单个子例程(或其他词法范围)添加支持. (如果没有通过NQP侵入Rakudo内部组件,实际上这些模块实际上是不可能的,但是一旦宏/俚语设计完成,它就会成为).
禁止看起来像是启动POD块的行的负担将被传递给所有那些俚语解析器.
您可以随时向Larry和其他Perl 6设计师提交功能请求,以便考虑这一点.