面向对象的Perl构造函数语法和命名参数 [英] Object-Oriented Perl constructor syntax and named parameters
问题描述
我对Perl构造函数中发生的事情有些困惑.我发现了这两个示例 perldoc perlbot .
I'm a little confused about what is going on in Perl constructors. I found these two examples perldoc perlbot.
package Foo;
#In Perl, the constructor is just a subroutine called new.
sub new {
#I don't get what this line does at all, but I always see it. Do I need it?
my $type = shift;
#I'm turning the array of inputs into a hash, called parameters.
my %params = @_;
#I'm making a new hash called $self to store my instance variables?
my $self = {};
#I'm adding two values to the instance variables called "High" and "Low".
#But I'm not sure how $params{'High'} has any meaning, since it was an
#array, and I turned it into a hash.
$self->{'High'} = $params{'High'};
$self->{'Low'} = $params{'Low'};
#Even though I read the page on [bless][2], I still don't get what it does.
bless $self, $type;
}
另一个例子是:
package Bar;
sub new {
my $type = shift;
#I still don't see how I can just turn an array into a hash and expect things
#to work out for me.
my %params = @_;
my $self = [];
#Exactly where did params{'Left'} and params{'Right'} come from?
$self->[0] = $params{'Left'};
$self->[1] = $params{'Right'};
#and again with the bless.
bless $self, $type;
}
这是使用这些对象的脚本:
And here is the script that uses these objects:
package main;
$a = Foo->new( 'High' => 42, 'Low' => 11 );
print "High=$a->{'High'}\n";
print "Low=$a->{'Low'}\n";
$b = Bar->new( 'Left' => 78, 'Right' => 40 );
print "Left=$b->[0]\n";
print "Right=$b->[1]\n";
我已经将我一直在思考的问题/困惑作为注释.
I've injected the questions/confusion that I've been having into the code as comments.
推荐答案
要回答您的问题,由于哈希可以初始化为key => value
对的列表,因此可以将此类列表发送给函数然后将@_
分配给哈希.这是在Perl中执行命名参数的标准方法.
To answer the main thrust of your question, since a hash can be initialized as a list of key => value
pairs, you can send such a list to a function and then assign @_
to a hash. This is the standard way of doing named parameters in Perl.
例如
sub foo {
my %stuff = @_;
...
}
foo( beer => 'good', vodka => 'great' );
这将导致子例程foo
中的%stuff
具有包含两个键beer
和vodka
以及相应值的散列.
This will result in %stuff
in subroutine foo
having a hash with two keys, beer
and vodka
, and the corresponding values.
现在,在OO Perl中,还有一些其他的皱纹.每当您使用箭头(->
)运算符调用方法时,箭头左侧的内容都会粘在@_
数组的开头.
Now, in OO Perl, there's some additional wrinkles. Whenever you use the arrow (->
) operator to call a method, whatever was on the left side of the arrow is stuck onto the beginning of the @_
array.
所以,如果您说Foo->new( 1, 2, 3 )
;
然后在构造函数中,@_
看起来像这样:( 'Foo', 1, 2, 3 )
.
Then inside your constructor, @_
will look like this: ( 'Foo', 1, 2, 3 )
.
因此,我们使用shift
,它不带参数地对@_
进行隐式运算,以将第一项从@_
中取出,并将其分配给$type
.之后,@_
仅剩下我们的名称/值对,为方便起见,我们可以将其直接分配给哈希.
So we use shift
, which without an argument operates on @_
implicitly, to get that first item out of @_
, and assign it to $type
. After that, @_
has just our name/value pairs left, and we can assign it directly to a hash for convenience.
然后将$type
值用于bless
. bless
所做的只是获取一个引用(在您的第一个示例中为哈希引用),然后说此引用与特定的程序包相关联". Alakazzam,您有一个物体.
We then use that $type
value for bless
. All bless
does is take a reference (in your first example a hash ref) and say "this reference is associated with a particular package." Alakazzam, you have an object.
请记住,$type
包含字符串"Foo",这是我们程序包的名称.如果您不为bless
指定第二个参数,它将使用当前程序包的名称,该名称在本示例中也适用,但 不适用于继承的构造函数.
Remember that $type
contains the string 'Foo', which is the name of our package. If you don't specify a second argument to bless
, it will use the name of the current package, which will also work in this example but will not work for inherited constructors.
这篇关于面向对象的Perl构造函数语法和命名参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!