在perl中如何使用公共关键字?
我见过这样的代码在perl中如何使用公共关键字?,perl,Perl,我见过这样的代码 package xyz; # putting the module inside its own pair of braces { public _foo => my %_foo; public _bar => my %_bar; # some subroutines.. } 1; 我的问题是公开声明的确切含义是什么_foo=>My%\u foo; 我的意思是如何使用public关键字,为什么我们要使用大箭头来分配另一个哈希 任何帮助
package xyz;
# putting the module inside its own pair of braces
{
public _foo => my %_foo;
public _bar => my %_bar;
# some subroutines..
}
1;
我的问题是公开声明的确切含义是什么_foo=>My%\u foo;
我的意思是如何使用public关键字,为什么我们要使用大箭头来分配另一个哈希
任何帮助都将不胜感激。哦,你正在使用吗
在这种情况下,它不是一个关键字,它实际上是一个子例程。它在包中设置一个存储变量,用作类属性
基本上,由内而外对象是在Perl中实现真正封装的一种方法。通常,Perl对象将其值存储在散列引用中,然后将散列引用返回给用户,如下所示:
package Foo;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
return bless {
foo => $args{foo},
bar => $args{bar},
}, $class;
}
sub get_foo {
my $self = shift;
return $self->{foo};
}
sub get_bar {
my $self = shift;
return $self->{bar};
}
1;
package Foo;
use strict;
use warnings;
use Scalar::Util qw/refaddr/;
{
my %_foo_of;
my %_bar_of;
sub new {
my ($class, %args) = @_;
# create a reference to an anonymous scalar.
my $instance = \do { my $anon_scalar };
$_foo_of{ refaddr $instance } = $args{foo};
$_bar_of{ refaddr $instance } = $args{bar};
return $instance;
}
# we have to manually delete these since they don't go out of scope
# automatically like standard Perl classes do!
sub DESTROY {
my $self = shift;
delete $_foo_of{ refaddr $self };
delete $_bar_of{ refaddr $self };
}
sub get_foo {
my $self = shift;
return $_foo_of{ refaddr $self };
}
sub get_bar {
my $self = shift;
return $_bar_of{ refaddr $self };
}
}
1;
如您所见,类所包含的详细信息实际上会返回给用户!他们可以在不使用访问器的情况下随心所欲地使用它。Whups
由内而外的对象使用这样一个事实,即包内的词汇变量(例如my
variables)永远无法在其范围之外看到。它利用了这样一个事实,即每个唯一标量引用都有一个唯一的地址,这给了我们一个进入散列的唯一键,允许我们为类数据提供一个唯一的、受限的存储。基本模式如下所示:
package Foo;
use strict;
use warnings;
sub new {
my ($class, %args) = @_;
return bless {
foo => $args{foo},
bar => $args{bar},
}, $class;
}
sub get_foo {
my $self = shift;
return $self->{foo};
}
sub get_bar {
my $self = shift;
return $self->{bar};
}
1;
package Foo;
use strict;
use warnings;
use Scalar::Util qw/refaddr/;
{
my %_foo_of;
my %_bar_of;
sub new {
my ($class, %args) = @_;
# create a reference to an anonymous scalar.
my $instance = \do { my $anon_scalar };
$_foo_of{ refaddr $instance } = $args{foo};
$_bar_of{ refaddr $instance } = $args{bar};
return $instance;
}
# we have to manually delete these since they don't go out of scope
# automatically like standard Perl classes do!
sub DESTROY {
my $self = shift;
delete $_foo_of{ refaddr $self };
delete $_bar_of{ refaddr $self };
}
sub get_foo {
my $self = shift;
return $_foo_of{ refaddr $self };
}
sub get_bar {
my $self = shift;
return $_bar_of{ refaddr $self };
}
}
1;
哎哟。很多样板。更多的模板工作。讨厌
现在让我们用Class::InsideOut
来看看它
package Foo;
use strict;
use warnings;
use Class::InsideOut qw/new public/;
public foo => my %foo;
public bar => my %bar;
1;
完成了
如果需要,您可以创建一个更复杂的new
子例程,但这会自动设置一个默认的new
子例程,用于从命名参数初始化foo
和bar
类::InsideOut使您不必做样板文件之类的事情。它为您创建访问器,为您创建匿名标量,为您创建析构函数,并为您提供nice
id
关键字,而不是refaddr。除此之外,一切都是一样的。它只是去除了一些您通常必须处理的样板文件,使得由内而外的类易于使用(而且很有趣!)。您确定这是Perl吗?它看起来不像我见过的任何Perl。可能是perl 6。这不是有效的perl5代码,除非使用第三方模块添加一些新语法(例如MooseX::Declare)。你能为上下文提供更多的代码吗?是的,科林和以太说过。在阅读问题时,我的眼睛确实做了一个O.O
。正如@Ether所说:“-第5行的语法错误,靠近“public\u foo”执行-由于编译错误而中止。”(这是“我见过这样的代码”问题的问题。“like”通常还不够“like”!:)嗨,Robert,你说得对,我使用的是Class::InsideOut qw(公共注册);我是Perl新手,这就是为什么我对InsideOut一无所知的原因。这段代码与我在教科书中读到的完全不同,就像其他人评论的一样。谢谢你的回答。现在我可以弄明白了!Arun