Perl:保证常量的单一评估吗?

两天内我第三个问题.有些人会说我不够努力研究,虽然我会说我正在帮助保持这个部分活跃:P无论哪种方式,我都在大声思索,希望得到一个答案.

不用多说了,让我引用常量pragma文档中的声明:

When a constant is used in an expression, Perl replaces it with its
value at compile time, and may then optimize the expression further.

我只想明确一点:这是否意味着每个程序执行只评估所有表达式一次?因为它还说它们是使用内联子设备构建的,这使我觉得它本身就是每次使用的评估.我的意思是,如果你得到一个返回表达式的sub,它会根据每次调用重新评估它,对吧?除非他们使用封闭变量或状态变量来评估一次,但我不知道.

可以肯定的是,我可以保证这只会评估一次吗?

#!/usr/bin/perl

use 5.014;
use autodie;
use strict;
use warnings;

use constant TEST => do {
    say 'Testing...';
    5;
};

say TEST foreach (1..4);

在这个特殊的例子中,我可以; ‘测试……’只打印一次.但是我保留了所有表达式吗?

耶耶耶.我应该在CPAN上使用Readonly.不幸的是,我来自Python的思路,你应该坚持尽可能多地采取标准的做法,因此我坚持使用复古的constant,因为它是一个核心的实用主义.

基本上,如果我将一个长复杂的sort / grep / map管道放入一个常量,我可以100%保证只进行一次评估吗?

窥孔优化器使用该子返回的值替换对常量subs的调用.在运行时optree中,没有对该sub的任何调用.例如:

$perl -MO=Concise -E\
  'sub answer () { 42 } for (1 .. 10) { say "The answer is ", answer }'
h  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 49 -e:1) v:%,2048 ->3
g     <2> leaveloop vK/2 ->h
7        <{> enteriter(next->d last->g redo->8) lKS/8 ->e
-           <0> ex-pushmark s ->3
-           <1> ex-list lK ->6
3              <0> pushmark s ->4
4              <$> const(IV 1) s ->5
5              <$> const(IV 10) s ->6
6           <$> gv(*_) s ->7
-        <1> null vK/1 ->g
f           <|> and(other->8) vK/1 ->g
e              <0> iter s ->f
-              <@> lineseq vK ->-
8                 <;> nextstate(main 48 -e:1) v:%,2048 ->9
c                 <@> say vK ->d
9                    <0> pushmark s ->a
a                    <$> const(PV "The answer is ") s ->b
b                    <$> const(IV 42) s ->c
d                 <0> unstack v ->e

这里有点兴趣

c                 <@> say vK ->d
9                    <0> pushmark s ->a
a                    <$> const(PV "The answer is ") s ->b
b                    <$> const(IV 42) s ->c
d                 <0> unstack v ->e

这表明say操作的参数是一个const字符串“答案是”和一个const整数42.没有enterub操作码代表一个子调用.

相关文章
相关标签/搜索