微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 Perl 中禁用常量折叠?

如何解决如何在 Perl 中禁用常量折叠?

给定一个命令,如

perl -MO=Deparse -E'use constant FOO => 42; print FOO()'

如何禁用常量折叠,以便

print 42;

给我看

print FOO();

之类的。 理想情况下,我希望这是一个适用于所有 Perl 的编译器选项。您可以在 perl 邮件列表 [perl #97942] [PATCH] Add -DO option to disable optimizations and disable constant folding and the peephole optimizer when used. 上的此线程中看到有关此内容的讨论。我试过 -DO 但没有用。如果该选项不起作用,我愿意接受变通方法,但它们可能会出现。

解决方法

常量将自己呈现为 subs。您可以使用 sub 执行的操作:

  • 将其作为函数调用 (FOO,FOO())
  • 在覆盖原型 (&FOO()) 时将其作为函数调用
  • 在继承 @_ (&FOO) 时将其作为函数调用
  • 将其作为方法调用 (__PACKAGE__->FOO)
  • 创建对它的引用(\&FOO*FOO{CODE}。还有需要代码引用的 *FOO。)

只有第一个被折叠。因此,您可以使用

$ perl -MO=Concise,-exec -E'use constant FOO=>42; say &FOO()' 2>&1 | grep FOO
5  <#> gv[*FOO] s
$ perl -MO=Concise,-exec -E'use constant FOO=>42; say &FOO' 2>&1 | grep FOO
5  <#> gv[*FOO] s
$ perl -MO=Concise,-exec -E'use constant FOO=>42; say __PACKAGE__->FOO' 2>&1 | grep FOO
6  <.> method_named[PV "FOO"] l
$ perl -MO=Concise,-exec -E'use constant FOO=>42; say+ (\&FOO)->()' 2>&1 | grep FOO
5  <#> gv[*FOO] s
$ perl -MO=Concise,-exec -E'use constant FOO=>42; say *FOO{CODE}->()' 2>&1 | grep FOO
5  <#> gv[*FOO] s
$ perl -MO=Concise,-exec -E'use constant FOO=>42; say *FOO->()' 2>&1 | grep FOO
5  <#> gv[*FOO] s
,

您可以做的一种方法是在常量前加上 &,

perl -MO=Deparse -E'use constant FOO => 42; print &FOO()'

来自 perldoc perlsub 上的文档

常量函数 具有“()”原型的函数是内联的潜在候选对象。如果优化和常量折叠后的结果是常量或没有其他引用的词法范围标量,则它将用于代替没有 & 的函数调用。使用 & 进行的调用永远不会内联。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。