为什么Perl源过滤器坏了,什么时候可以使用它们?

dao*_*oad 23 perl source-filter

源过滤器是坏的并且不应该在生产代码中使用是"常识" .

在回答类似但更具体的问题时,我找不到任何好的参考资料,清楚地解释了为什么过滤器是坏的以及何时可以安全使用.我想现在是时候创造一个了.

  1. 为什么源过滤器不好?
  2. 什么时候可以使用源过滤器?

Mic*_*man 23

为什么源过滤器很糟糕:

  1. 只有perl可以解析Perl.(源过滤器很脆弱.)
  2. 当源过滤器几乎完全破坏时,任何事情都会发生.(它们可以引入微妙且非常难以发现的错误.)
  3. 源过滤器可以破坏使用源代码的工具.(PPI,重构,静态分析等)
  4. 源过滤器是互斥的.(你不能一次使用多个 - 除非你是精神病患者).

当他们没事的时候:

  1. 你正在试验.
  2. 你正在写丢弃代码.
  3. 你的名字是Damian,你必须被允许用拉丁语编程.
  4. 你在Perl 6编程.


Sin*_*nür 19

只能perl解析Perl(参见本例):

@result = (dothis $foo, $bar);

# Which of the following is it equivalent to?
@result = (dothis($foo), $bar);
@result = dothis($foo, $bar);
Run Code Online (Sandbox Code Playgroud)

这种模糊性使得编写始终成功并做正确事情的源过滤器变得非常困难.当出现问题时,调试很尴尬.

在崩溃和刻录几次之后,我开发了一种从不尝试编写另一个源过滤器的迷信方法.

不过,我偶尔会使用Smart :: Comments进行调试.当我这样做时,我在命令行上加载模块:

$ perl -MSmart::Comments test.pl
Run Code Online (Sandbox Code Playgroud)

以避免在生产代码中保持启用的可能性.

另请参阅: Perl无法解析:正式证明

  • 根据`$ perl -MO = Deparse -e'@result =(dothis $ foo,$ bar)'`它解析为`@result =($ foo-> dothis,$ bar);`谈论模棱两可.如果我们预先声明`sub dothis`没有原型或`($$)`或`(@)`的原型,它解析为`@result = dothis($ foo,$ bar)`.它只解析为`@result =(dothis($ foo),$ bar)`如果我们用`($)`的原型声明它. (4认同)

bri*_*foy 10

我不喜欢源过滤器,因为你不能通过阅读它来告诉我们要做什么代码.此外,看起来像它们不可执行的东西,例如注释,可能会神奇地使用过滤器执行.您(或更可能是您的同事)可以删除您认为不重要的内容并破坏内容.

话虽如此,如果您要实现自己想要转换为Perl的小语言,源过滤器可能是正确的工具.但是,不要称之为Perl.:)

  • Perl 6明确设计为具有用户可扩展的语法; 它的一个座右铭是"如果你预先宣布,那就是公平的" (3认同)

hob*_*bbs 6

值得一提的是,Devel::Declare关键字(从Perl 5.11.2开始,可插入的关键字)不是源过滤器,并且不会与"只有perl可以解析Perl"问题相冲突.这是因为它们由perl解析器本身运行,它们从输入中获取它们所需的内容,然后它们将控制权返回给同一个解析器.

例如,当您MooseX::Declare像这样声明一个方法时:

method frob ($bubble, $bobble does coerce) {
  ... # complicated code
}
Run Code Online (Sandbox Code Playgroud)

单词"method"调用方法关键字解析器,它使用自己的语法来获取方法名称并解析方法签名(不是Perl,但它不需要 - 它只需要很好 - 定义).然后它离开perl来解析方法体作为sub的主体.任何在你的代码的任何地方是不是该"方法"一词和方法签名的末端之间没有得到该方法解析器看到可言,所以它不能破坏你的代码,无论你怎么弄猫腻.