如何在 Perl 中禁用常量折叠?
How can I disable constant folding in 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
但没有成功。如果该选项不起作用,我愿意接受变通方法,但它们可能会出现。
您可以采用的一种方法是在常量前加上 &
、
perl -MO=Deparse -E'use constant FOO => 42; print &FOO()'
来自 perldoc perlsub
上的文档
Constant Functions
Functions with a prototype of "()" are potential candidates for inlining. If the result after optimization and constant folding is either a constant or a lexically-scoped scalar which has no other references, then it will be used in place of function calls made without &
. Calls made using &
are never inlined.
常量以 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()'
如何禁用常量折叠,这样
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
但没有成功。如果该选项不起作用,我愿意接受变通方法,但它们可能会出现。
您可以采用的一种方法是在常量前加上 &
、
perl -MO=Deparse -E'use constant FOO => 42; print &FOO()'
来自 perldoc perlsub
Constant Functions Functions with a prototype of "()" are potential candidates for inlining. If the result after optimization and constant folding is either a constant or a lexically-scoped scalar which has no other references, then it will be used in place of function calls made without
&
. Calls made using&
are never inlined.
常量以 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