为什么 `exists` 会修改我的常量?

发布于 2024-09-28 10:08:57 字数 1116 浏览 6 评论 0原文

exists 函数可以 意外地自动激活哈希中的条目

令我惊讶的是,这种行为也适用于常量:

use strict;
use warnings;
use Data::Dump 'dump';

use constant data => {
                       'foo' => {
                                  'bar' => 'baz',
                                },
                       'a'   => {
                                  'b'   => 'c',
                                }
                     };

dump data;   # Pre-modified

print "No data for 'soda->cola->pop'\n" unless exists data->{soda}{cola}{pop};

dump data;   # data->{soda}{cola} now sprung to life

输出

{ a =>; { b => "c" }, foo =>; { 栏 => “巴兹”}}
没有“苏打水->可乐->汽水”的数据
{ 一个 => { b =>; "c" }, foo =>; { 栏 => “baz”},苏打水=> { 可乐 => {} } }

我怀疑这是一个错误。这是 5.10.1 特有的,还是其他版本的 Perl 行为类似?

The exists function can unexpectedly autovivify entries in hashes.

What surprises me is that this behavior carries over to constants as well:

use strict;
use warnings;
use Data::Dump 'dump';

use constant data => {
                       'foo' => {
                                  'bar' => 'baz',
                                },
                       'a'   => {
                                  'b'   => 'c',
                                }
                     };

dump data;   # Pre-modified

print "No data for 'soda->cola->pop'\n" unless exists data->{soda}{cola}{pop};

dump data;   # data->{soda}{cola} now sprung to life

Output

{ a => { b => "c" }, foo => { bar => "baz" } }
No data for 'soda->cola->pop'
{ a => { b => "c" }, foo => { bar => "baz" }, soda => { cola => {} } }

I suspect this is a bug. Is this something 5.10.1-specific, or do other versions of Perl behave similarly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

时光匆匆的小流年 2024-10-05 10:08:57

这是有记录的行为。 perldoc 常量 说:

尽管参考可能是
声明为常量,引用
可能指向的数据可能是
已更改,如这段代码所示。

使用常量 ARRAY => [1,2,3,4];
打印数组->[1];
ARRAY->[1] = "被改变";
打印数组->[1];

不变的是引用,而不是它所指的内容。

This is documented behaviour. perldoc constant says:

Even though a reference may be
declared as a constant, the reference
may point to data which may be
changed, as this code shows.

use constant ARRAY => [ 1,2,3,4 ];
print ARRAY->[1];
ARRAY->[1] = " be changed";
print ARRAY->[1];

It's the reference that is constant, not what it refers to.

懒的傷心 2024-10-05 10:08:57

您可能想使用 Readonly 来创建“true”常量。

使用 constant 编译指示创建的常量实际上是可内联子例程 。这意味着在编译时直接插入适当的标量常量来代替某些子例程调用。如果常量是引用,则没有什么可以阻止您更改它指向的数据。

You probably want to use Readonly for creating "true" constants.

Constants created using the constant pragma are actually inlinable subroutines. It means that at compile time the appropriate scalar constant is inserted directly in place of some subroutine call. If the constant is a reference, nothing prevents you from changing the data it points to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文