PERL:ref,shift关键字

时间:2016-03-15 19:55:46

标签: perl

我正在经历以下子程序:

sub new{
    my $self  = shift;
    my $class = ref($self) || $self;
} 

在这里,我不明白shift用于什么?我从谷歌搜索中了解到,shift返回并删除数组最左边的值。但我仍然不确定。

另一个问题,ref用于什么?谷歌表示它充当typeof函数,返回类似scalararrayhashes的类型。

我仍然不确定我的理解。有人可以澄清一下吗?

1 个答案:

答案 0 :(得分:3)

当您在Perl中调用子例程时,您提供的任何参数都将可用于名为@_的特殊数组中的子例程。

shift函数将数组作为参数,从数组中删除第一个元素并返回该值。

但是,如果你在没有传递数组的情况下调用shift,它就会在@_数组上运行。

例如,如果你调用这样的子程序:

my_sub('one', 'two', 'three');

my_sub的定义是这样开始的:

sub my_sub {
    my $arg1 = shift;

然后$arg1变量将包含字符串'one'@_数组将保留('two', 'three')

您尝试理解的代码似乎与面向对象的编码有关。如果你在这样的对象上调用一个方法:

$obj->my_method('one');

然后my_method子例程实际上将在@_中传递两个参数。第一个是调用该方法的对象(有时称为invocant),在此示例中为$obj。第二个参数是字符串'one'

在面向对象的代码中,很常见的是启动这样的方法定义:

sub my_method {
    my $self = shift;

这意味着$self现在将包含调用者,@_将留下所有剩余的参数。

在您的具体示例中,您正在查看构造函数,这是一种特殊的方法。通常会这样调用:

my $my_obj = MyClass->new($arg1, $arg2);

在这种情况下,调用者将是调用new方法的类的名称 - 在此示例中为字符串'MyClass'

也可以在现有对象上调用构造函数,如下所示:

my $new_obj = $my_obj->new($arg1, $arg2);

这个电话的结果究竟应该是什么,对于随意的读者来说并不是很清楚。它应该是一个全新的对象,是$my_obj的克隆,还是应该是一个与$my_obj完全没有共同点的新对象?在第一种情况下,定义clone方法会更清楚,在第二种情况下,调用类上的构造函数会更清楚。

您的示例代码正在尝试处理这两种情况。如果调用者是一个类,那么ref($self)将返回undef,因为纯字符串(类名)不是引用。如果调用者是一个对象,那么ref($self)将返回该对象所属的类的名称。

如果您正试图了解Perl对OO编程的本机支持,请从the standard tutorial doc开始。如果您只想使用Perl进行OO编程,请从Moose开始。