问题
Given a command like,
perl -MO=Deparse -E'use constant FOO => 42; print FOO()'
How can I disable constant folding such that
print 42;
Shows me
print FOO();
Or the like. Ideally, I would like this to be a compiler option that works for all of Perl. You can see this talked about in this thread on the perl mailing list, [perl #97942] [PATCH] Add -DO option to disable optimizations and disable constant folding and the peephole optimizer when used.. I tried -DO
and it didn't work. If that option doesn't work, I'm open to workarounds however they may come.
回答1:
Constants present themselves as subs. Things you can do with a sub:
- Call it as a function (
FOO
,FOO()
) - Call it as a function while overriding prototypes (
&FOO()
) - Call it as a function while inheriting
@_
(&FOO
) - Call it as a method (
__PACKAGE__->FOO
) - Create a reference to it (
\&FOO
,*FOO{CODE}
. Also*FOO
where a code ref is expected.)
Only the first gets folded. As such, you could use
$ 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
回答2:
One method you can do is to prefix the constant with &
,
perl -MO=Deparse -E'use constant FOO => 42; print &FOO()'
From the docs on 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.
来源:https://stackoverflow.com/questions/66038302/how-can-i-disable-constant-folding-in-perl