在什么情况下实例变量声明为“_var”?在“使用字段”中私人的?
我试图理解 fields
编译指示的行为,我发现它很差已记录,有关以下划线前缀的字段。这是文档对此的说明:
以下划线字符开头的字段名称对类而言是私有的,并且对子类不可见。继承的字段可以被覆盖,但如果与 -w 开关一起使用,则会生成警告。
根据我的测试,这与其实际行为不一致,如下。以 _
为前缀的字段不仅在子类中可见,而且在外部类中也可见(除非我不明白“可见”的含义)。此外,直接访问受限哈希也可以正常工作。
除了源代码之外,我在哪里可以找到有关 fields
pragma 行为的更多信息?
{
package Foo;
use strict;
use warnings;
use fields qw/a _b __c/;
sub new {
my ( $class ) = @_;
my Foo $self = fields::new($class);
$self->a = 1; $self->b = 2; $self->c = 3;
return $self;
}
sub a : lvalue { shift->{a} }
sub b : lvalue { shift->{_b} }
sub c : lvalue { shift->{__c} }
}
{
package Bar;
use base 'Foo';
use strict;
use warnings;
use Data::Dumper;
my $o = Bar->new;
print Dumper $o; ##$VAR1 = bless({'_b' => 2, '__c' => 3, 'a' => 1}, 'Foo');
$o->a = 4; $o->b = 5; $o->c = 6;
print Dumper $o; ##$VAR1 = bless({'_b' => 5, '__c' => 6, 'a' => 4}, 'Foo');
$o->{a} = 7; $o->{_b} = 8; $o->{__c} = 9;
print Dumper $o; ##$VAR1 = bless({'_b' => 8, '__c' => 9, 'a' => 7}, 'Foo');
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
巧合的是,我碰巧在
~/codescraps/fields/test.pl
中有一个测试脚本,该脚本可以追溯到两年前,当时我尝试回答完全相同的问题。 :)当我运行你的代码时,我收到错误:(
第 16 行是 sub b 的定义。)你在什么架构上运行这个?使用 fields pragma 的对象不是简单的受祝福的哈希引用 - 它们是受祝福的数组引用,例如,当我将构造函数修改为如下所示时:
我看到:
作为后记,我觉得有必要指出 fields 编译指示,以及 base pragma 均已弃用,强烈建议避免使用它们。如今,如果您希望使用访问器构建一个漂亮的面向对象模块,可以使用 Class ::Accessor 或直接转到 Moose。
Coincidentally enough, I happen to have a test script in
~/codescraps/fields/test.pl
dated from two years ago when I experimented with answering exactly this same question. :)And when I run your code, I get the error:
(line 16 is the definition for sub b.) What architecture are you running this on? Objects using the fields pragma aren't simple blessed hashrefs -- they are blessed arrayrefs, e.g. when I modify your constructor to look like this:
I see:
As a postscript, I feel obliged to point out that the fields pragma, and the base pragma that goes with it, are both deprecated and one is strongly urged to avoid using them. Nowadays, if you're looking to construct a nice OO module with accessors, one would either use Class::Accessor or go directly to Moose.