0,1. В Perl конструктор - это просто подпрограмма с именем new.
Да, по соглашению new
это конструктор. Может также выполнить инициализацию или нет. new
должен вернуть объект в случае успеха или выдать исключение (die
/ croak
), если произошла ошибка, препятствующая созданию объекта.
Вы можете называть свой конструктор как угодно, иметь столько конструкторов, сколько хотите, и даже встраивать благословенные объекты в любое пространство имен, которое пожелаете (не то, чтобы это была хорошая идея).
0,2. Я совсем не понимаю, что делает my $type = shift;
, но я всегда это вижу. Мне это нужно?
shift
без аргументов снимает аргумент с заголовка @_
и присваивает его $type
. Оператор ->
передает инвокант (левая сторона) в качестве первого аргумента подпрограмме. Таким образом, эта строка получает имя класса из списка аргументов. И да, тебе это нужно.
0,3. Как массив входных данных становится хешем %params
? my %params = @_;
Назначение в хеш выполняется в контексте списка, при этом пары элементов списка группируются в пары ключ / значение. Так что %foo = 1, 2, 3, 4;
создает хеш, такой что $foo{1} == 2
и $foo{3} == 4
. Обычно это делается для создания именованных параметров для подпрограммы. Если подпрограмме передается нечетное число аргументов, то предупреждение будет сгенерировано, если предупреждения включены.
0,4. Что делает 'my $ self = {}; `do?
Эта строка создает анонимную ссылку на хеш и присваивает ее лексической переменной $self
. Ссылка на хеш будет хранить данные для объекта. Как правило, ключи в хэше имеют однозначное соответствие атрибутам объекта. Поэтому, если у класса Foo есть атрибуты 'size' и 'color', если вы проверите содержимое объекта Foo, вы увидите что-то вроде $foo = { size => 'm', color => 'black' };
.
0,5. Учитывая $self->{'High'} = $params{'High'};
откуда $params{'High'}
откуда?
Этот код опирается на аргументы, переданные new
. Если new
был назван как Foo->new( High => 46 )
, то хэш, созданный в соответствии с вопросом 3, будет иметь значение для ключа High
(46). В этом случае это эквивалентно высказыванию $self->{High} = 46
. Но если метод вызывается как Foo->new()
, тогда никакое значение не будет доступно, и у нас будет $self->{High} = undef
.
0,6. Что bless
делает?
bless
берет ссылку и связывается с конкретным пакетом, так что вы можете использовать его для вызова методов. С одним аргументом ссылка ассоциируется с текущим пакетом. С двумя аргументами второй аргумент указывает пакет, с которым связана ссылка. Лучше всегда использовать форму с двумя аргументами, чтобы ваши конструкторы могли наследоваться подклассом и при этом функционировать должным образом.
Наконец, я перепишу ваш метод доступа к объектам, основанный на хэше, как я написал бы, используя классический OO Perl.
package Foo;
use strict;
use warnings;
use Carp qw(croak);
sub new {
my $class = shift;
croak "Illegal parameter list has odd number of values"
if @_ % 2;
my %params = @_;
my $self = {};
bless $self, $class;
# This could be abstracted out into a method call if you
# expect to need to override this check.
for my $required (qw{ name rank serial_number });
croak "Required parameter '$required' not passed to '$class' constructor"
unless exists $params{$required};
}
# initialize all attributes by passing arguments to accessor methods.
for my $attrib ( keys %params ) {
croak "Invalid parameter '$attrib' passed to '$class' constructor"
unless $self->can( $attrib );
$self->$attrib( $params{$attrib} );
}
return $self;
}