#perl #oop #object #object-composition
#perl #ооп #объект #объект-композиция
Вопрос:
У меня есть класс A со следующим конструктором:
sub new {
my ($class, %args) = @_;
return bless(%args, $class);
}
У меня есть другой класс, LWP::UserAgent, который я хочу использовать в своем классе A.
Я мог бы решить проблему, выполнив это:
ua = LWP::UserAgent->new;
sub new {
my ($class, %args) = @_;
return bless(%args, $class);
}
Но в этом случае у меня будет 1 объект UserAgent, но мне нужен уникальный объект для каждого экземпляра моего класса A.
Ответ №1:
Затем вам нужно создать этот объект как атрибут
use LWP::UserAgent;
sub new {
my ($class, %args) = @_;
return bless { %args, lwp => LWP::UserAgent->new }, $class;
}
и теперь каждый объект класса A будет иметь для атрибута lwp
свой LWP::UserAgent
объект.
Я бы, конечно, ожидал, что на самом деле это хорошо прописано со всей необходимой проверкой ошибок.
И я думаю, что лучше вызвать атрибут ua
(вместо lwp
указанного выше) для User-Agent.
Комментарии:
1. Не могли бы вы, пожалуйста, сказать мне следующее: является ли «{ %args, lwp => LWP::UserAgent-> new }» таким же, как следующий код?
$args{lwp} = LWP::UserAgent->new; return bless(%args, $class);
2. @Nazar Да, и выполнение
%args
(немного) более эффективно, чем копирование его с помощью{ %args }
. Однако это делается один раз за время существования объекта. Сколько объектов создает этот код? Я бы написал это красиво — я думаю, вам действительно нужно, чтобы проверить пользовательский ввод (%args
).3. Я не думаю, что создам более 2-3 объектов. Но просто чтобы быть гибким, я решил перенести эту логику из класса в экземпляр. Я использую Params::ValidationCompiler для проверки ввода пользователем *, но не объекта lwp. Поскольку объект lwp является внутренним, и я не хочу, чтобы пользователь изменял его на шаге конструктора.
4. @Nazar Ах, хорошо, у вас есть (даже правильная!) проверка на месте. (Я не знаю модуль, но могу ожидать, что он хорош.)
5. Да 🙂 Еще раз спасибо за вашу помощь!