8

我想知道,是否-MO=Deparse向您展示了所有 Perl 优化,为什么不将其折叠到 Perl 5.10 中?

$ perl -MO=Deparse -e'[qw/foo bar baz/]->[0]'
['foo', 'bar', 'baz']->[0];
-e syntax OK

IRC 上的一些人认为这O=Deparse可能没有显示全部,但它肯定显示了一些不断的折叠。

$ perl -MO=Deparse -e'use constant "foo" => "bar"; foo'
use constant ('foo', 'bar');
'???';
-e syntax OK

如果我显式编写常量 sub,结果相同。constant.pm虽然可以预测,但其中的文档让您创建一个常量列表而不是一个常量数组也很有趣。我假设这不仅不像标量常量那样折叠,而且它需要在每次调用时创建一个新数组的开销。

$ perl -MO=Deparse -e'use constant foo => qw/foo bar baz/; (foo)[0]'
use constant ('foo', ('foo', 'bar', 'baz'));
(foo)[0];
-e syntax OK

我能得出的唯一结论-MO=Deparse是显示所有折叠,而常量数组只是没有在 Perl 中优化?是这样吗?有技术原因吗?

4

2 回答 2

9

您不能创建常量数组,因为数组不是数据。Perl 5 有五种类型的数据(可以存储在变量中的东西):

  • 无价值(未定义)
  • 数字
  • 字符串
  • 参考
  • 列表(由一种或多种先前类型组成)

您可以将其中任何一个设为常数。Perl 5 也有三个容器:

  • 标量
  • 大批
  • 哈希

标量可以保存前四种数据类型中的任何一种,数组和散列可以保存列表。重要的是不要混淆保存数据的东西和数据本身。

至于B::Deparse,它会在构建后转储 optree,因此它会显示所有常量折叠的结果。

我还没有充分考虑它,但我没有看到任何明显的原因表明它不能折叠。

于 2010-08-24T21:48:19.533 回答
8

你不能在 Perl 中创建一个常量数组,内部没有任何东西可以指示一个常量数组或散列,甚至是一个标量。“使用常量”利用了 Perl 将子例程与原型()和简单代码内联的能力。您可以做的最好的事情是设置只读标志,但可以在运行时将其关闭。

Perl 可以在编译时使用 readonly 标志作为提示来指示数组确实是只读的,然后使用常量索引内联任何访问。这种启发式方法可能是安全的,因为只读标志不应该是用户可访问的,而且您可能不应该将其关闭。

于 2010-08-24T22:51:23.710 回答