Perl / ООП: как создать объект «класса B» в конструкторе «Класса A»

#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. Да 🙂 Еще раз спасибо за вашу помощь!