如何在创建对象时初始化特定的类变量?

时间:2017-10-16 15:41:57

标签: perl oop

到目前为止,我总是依赖于类中变量的顺序,但现在我正在尝试以洗牌顺序初始化这些变量。

例如,这是我在创建对象时通常所做的事情。

my $person1 = Person->new ('Fernando', 'Alonso', 36);

这就是我想要实现的目标。

my $person2 = Person->new (Age => 36, FistName => 'Fernando', LastName => 'Alonso');

我尝试=>关于我看到的几个文件(例如perldoc),但他们没有给我一个完整的例子。但是我实际上并没有使用下面的脚本,这是一个公平的MCVE,带有'cliché'包Person

use strict;
use warnings;

package Person;
sub new {
  my $class = shift;
  my $self = {
    FirstName => shift,
    LastName  => shift,
    Age       => shift,
  };
  print "First name : $self->{FirstName}\n";
  print "Last name  : $self->{LastName}\n";
  print "Age        : $self->{Age}\n\n";
  bless  $self, $class;
  return $self;
}

# Works well
my $person1 = Person->new ('Fernando', 'Alonso', 36);

# (?) How to assign 36 directly to $self->{Age}
my $person2 = Person->new (Age => 36, '', '');

输出如下。

First name : Fernando
Last name  : Alonso
Age        : 36

First name : Age
Last name  : 36
Age        : 

那么,我应该如何创建对象来对类变量进行显式赋值?如有必要,我应该如何修改包Person

P.S。我避免在创建对象后更改变量。

1 个答案:

答案 0 :(得分:5)

原始Person类构造函数希望参数包含特定顺序的值,但您希望指定键值对。通过将输入表示为哈希引用,这很容易。

package Person;
sub new {
  my $class = shift;

  # read @_ as list of key-value pairs; 
  # set $self as reference to hash of these pairs
  my $self = { @_ };       
  #my $self = { my %args = @_ };   # if you like your abstractions unbroken 

  bless  $self, $class;
  return $self;
}

如果您想限制可以设置为FirstNameLastNameAge的密钥,您可以执行以下操作。

package Person;
sub new {
  my $class = shift;
  my %args = @_;
  my $self = {
    FirstName => $args{FirstName},
    LastName  => $args{LastName},
    Age       => $args{Age},
  };
  bless  $self, $class;
  return $self;
}

作为进一步的增强功能,您可以在调用者未指定所有预期键的情况下提供默认值

package Person;
sub new {
  my $class = shift;
  my %args = @_;
  my $self = {
    FirstName => $args{FirstName} // "Fred",
    LastName  => $args{LastName} // "Flinstone",
    Age       => $args{Age} // 42,
  };
  bless  $self, $class;
  return $self;
}