面向对象的概念如何在Perl中运行

Bel*_*day 1 oop perl

我正在读一本关于perl的书,到目前为止,我理解了OOP的概念,直到我遇到这个代码:

sub new {
    my $invocant = shift;
    my $class   = ref($invocant) || $invocant;
    my $self = {
        color  => "bay",
        legs   => 4,
        owner  => undef,
        @_,                 # Override previous attributes
    };
    return bless $self, $class;
}
$ed       = Horse->new;                    # A 4-legged bay horse
$stallion = Horse->new(color => "black");  # A 4-legged black horse
Run Code Online (Sandbox Code Playgroud)

我在该代码中看到的是,在new子例程中传递的任何内容都被视为包名称,该名称将使用以下代码转换为对象引用:

my $invocant = shift; #this one just get the name of the package which is the argument passed

return bless $self, $class;

  1. 现在哈希的预先声明(非空哈希)的用途是什么?为什么@_在列表的最后部分提供?做什么的?

接下来是基于上述代码的声明:

当用作实例方法时,此Horse构造函数会忽略其调用者的现有属性.您可以创建第二个构造函数,该函数被设计为作为实例方法调用,如果设计正确,您可以使用调用对象中的值作为新函数的默认值:

其中90%的陈述我不明白.

  1. 什么是实例方法?或对象方法?你能提供一个例子吗?

我知道这个my $class = ref($invocant) || $invocant;是对象和实例方法,但我不确定它们如何不同或如何以不同方式使用它们.

上面提到的"第二个构造函数"是这样的:

$steed  = Horse->new(color => "dun");
$foal   = $steed->clone(owner => "EquuGen Guild, Ltd.");
sub clone {
    my $model = shift;
    my $self  = $model->new(%$model, @_);
    return $self;     # Previously blessed by ->new
}
Run Code Online (Sandbox Code Playgroud)

再一次,我不知道它做了什么.所以任何人都可以为我澄清这一点.

DVK*_*DVK 5

现在哈希的预先声明(非空哈希)的用途是什么?为什么在列表的最后部分提供@_?做什么的?

这是一种非常聪明的方法,可以让您同时实现两件事:

  1. 允许您拥有构造函数的默认值

  2. 允许您使用已传入构造函数调用的一些(或全部)默认值.


这是如何运作的?根据您需要了解的有关哈希的3件事:

  • 通过展平为"key1","value1","key2","value2"......列表,可以将散列视为列表.如果将散列作为参数传递给子例程,则会发生这种情况:mySub(%hash1)

  • 可以通过反向过程将列表(具有偶数元素)转换为哈希.

  • 从列表构造的哈希,其中多次遇到某个键,将只有该键一次,并且 - 这里很重要 - 结果哈希中该键的值将是与该键关联的值中的最后一个实例.

换句话说,以下4个分配产生相同的精确结果数据结构:


    my %hash1;
    $hash1{20} = 2;
    $hash1{40} = 4;

    my %hash2 = ( 20, 2, 40, 4); # Notice that "," is same as "=>"

    my %hash3 = ( 20 => 2, 40 => 4); # Notice that "," is same as "=>"

    my %hash4 = ( 40 => 1, 40 => 3, 20 => 2, 40 => 4); 
    # first 2 couples will be effectively ignored, due to same keys later on
Run Code Online (Sandbox Code Playgroud)

例:

  • 如果你传入一个没有color键但是腿的哈希:Horse->new(legs=>3)

    • @_ 数组将包含2个元素,"leg"和"3"(通过展平该哈希获得).

    • 您的新哈希 - 将被分配给$self- 将由以下列表构建:

       ("color","bay", 
       "legs", "4", # Will get overwritten
       # more 
       "legs", "3")
      
      Run Code Online (Sandbox Code Playgroud)
    • 现在,按照上面的第三个子弹,"leg","4"对被后来的"leg","3"覆盖在哈希赋值中; 因此产生的散列将具有(默认)值为"bay"的颜色,以及pass-via-constructor-arguments值为"3"的腿.