我正在经历以下子程序:
sub new{
my $self = shift;
my $class = ref($self) || $self;
}
在这里,我不明白shift
用于什么?我从谷歌搜索中了解到,shift
返回并删除数组最左边的值。但我仍然不确定。
另一个问题,ref
用于什么?谷歌表示它充当typeof
函数,返回类似scalar
,array
,hashes
的类型。
我仍然不确定我的理解。有人可以澄清一下吗?
答案 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开始。