Spec-Zone.ru › Perl 5.34

perlootut

СОДЕРЖАНИЕ

  • ИМЯ
  • ДАТА
  • ОПИСАНИЕ
  • ОСНОВЫ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ
    • Объект
    • Класс
      • Благословение
      • Конструктор
    • Методы
    • Атрибуты
    • Полиморфизм
    • Наследование
      • Переопределение методов и разрешение методов
    • Инкапсуляция
    • Композиция
    • Роли
    • Когда использовать ООП
  • СИСТЕМЫ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ В PERL
    • Moose
      • Moo
    • Class::Accessor
    • Class::Tiny
    • Role::Tiny
    • Обзор систем ООП
    • Другие системы ООП
  • ЗАКЛЮЧЕНИЕ

ИМЯ

perlootut - Руководство по объектно-ориентированному программированию на Perl

ДАТА

Этот документ был создан в феврале 2011 года, а последняя крупная редакция была в феврале 2013 года.

Если вы читаете это в будущем, то возможно, что состояние дел изменилось. Мы рекомендуем вам начать с чтения документа perlootut в последней стабильной версии Perl, а не этой версии.

ОПИСАНИЕ

Этот документ предоставляет введение в объектно-ориентированное программирование на Perl. Он начинается с краткого обзора концепций объектно-ориентированного проектирования. Затем он представляет несколько различных систем ООП из CPAN, которые строятся поверх возможностей Perl.

По умолчанию встроенная система ООП Perl очень минимальна, оставляя вам большую часть работы. Эта минимальность имела смысл в 1994 году, но за прошедшие годы после Perl 5.0 мы увидели множество общих шаблонов в Perl ООП. К счастью, гибкость Perl позволила развиться богатому экосистеме систем Perl ООП.

Если вы хотите узнать, как работает Perl ООП под капотом, документ perlobj объясняет подробности.

Этот документ предполагает, что вы уже знакомы с основами синтаксиса Perl, типами переменных, операторами и вызовами подпрограмм. Если вы еще не понимаете эти концепции, пожалуйста, сначала прочтите perlintro. Вы также должны прочитать документы perlsyn, perlop и perlsub.

ОСНОВЫ ОБЪЕКТНО-ОРИЕНТИРОВАННОГО ПРОГРАММИРОВАНИЯ

Большинство объектных систем разделяют ряд общих концепций. Вероятно, вы уже слышали такие термины, как «класс», «объект», «метод» и «атрибут». Понимание этих концепций значительно упростит чтение и написание объектно-ориентированного кода. Если вы уже знакомы с этими терминами, все равно стоит просмотреть этот раздел, так как в нем каждая концепция объясняется в терминах реализации ООП в Perl.

Система ООП Perl основана на классах. Класс-ориентированное ООП довольно распространено. Оно используется в Java, C++, C#, Python, Ruby и во многих других языках. Существуют и другие парадигмы объектно-ориентированного программирования. JavaScript — наиболее популярный язык, использующий другую парадигму. Система ООП JavaScript основана на прототипах.

Объект

Объект — это структура данных, которая объединяет данные и подпрограммы, которые работают с этими данными. Данные объекта называются атрибутами, а подпрограммы — методами. Объект можно рассматривать как существительное (человек, веб-сервис, компьютер).

Объект представляет собой отдельную дискретную вещь. Например, объект может представлять собой файл. Атрибуты для объекта файла могут включать его путь, содержимое и время последней модификации. Если мы создали объект для представления /etc/hostname на машине с именем "foo.example.com", путь этого объекта будет "/etc/hostname", его содержимое — "foo\n", а время последней модификации — 1304974868 секунд с начала эпохи.

Методы, связанные с файлом, могут включать rename() и write().

В Perl большинство объектов являются хешами, но рекомендуемые системы ООП избавляют вас от необходимости беспокоиться об этом. На практике лучше всего рассматривать внутреннюю структуру данных объекта как непрозрачную.

Класс

Класс определяет поведение категории объектов. Класс — это имя категории (например, «Файл»), и класс также определяет поведение объектов в этой категории.

Все объекты принадлежат определенному классу. Например, наш объект /etc/hostname принадлежит к классу File. Когда мы хотим создать конкретный объект, мы начинаем с его класса и создаем или инициализируем объект. Конкретный объект часто называют экземпляром класса.

В Perl любой пакет может быть классом. Разница между пакетом, который является классом, и тем, который им не является, основана на том, как используется пакет. Вот наше «объявление класса» для класса File:

package File;

В Perl нет специального ключевого слова для создания объекта. Однако большинство модулей ООП в CPAN используют метод с именем new() для создания нового объекта:

my $hostname = File->new(
    path          => '/etc/hostname',
    content       => "foo\n",
    last_mod_time => 1304974868,
);

(Не беспокойтесь об операторе ->, он будет объяснен позже.)

Благословение

Как мы уже говорили, большинство объектов Perl являются хешами, но объект может быть экземпляром любого типа данных Perl (скаляр, массив и т. д.). Преобразование обычной структуры данных в объект выполняется путем благословения этой структуры данных с помощью функции Perl bless.

Хотя мы настоятельно рекомендуем вам не создавать объекты с нуля, вы должны знать термин благословение. Благословенная структура данных (также «ссылочный объект») — это объект. Иногда мы говорим, что объект был «благословлен в класс».

После того, как referent был благословлен, функция blessed из модуля ядра Scalar::Util может сообщить нам имя его класса. Эта подпрограмма возвращает имя класса объекта, если ей передан объект, и ложь в противном случае.

use Scalar::Util 'blessed';

print blessed($hash);      # undef
print blessed($hostname);  # File

Конструктор

Конструктор создает новый объект. В Perl конструктор класса — это просто другой метод, в отличие от некоторых других языков, которые предоставляют синтаксис для конструкторов. Большинство классов Perl используют new в качестве имени своего конструктора:

my $file = File->new(...);

Методы

Вы уже узнали, что метод — это подпрограмма, которая работает с объектом. Вы можете рассматривать метод как действия, которые объект может выполнять. Если объект — это существительное, то методы — это глаголы (сохранить, напечатать, открыть).

В Perl методы — это просто подпрограммы, которые находятся в пакете класса. Методы всегда пишутся таким образом, чтобы получать объект в качестве первого аргумента:

sub print_info {
    my $self = shift;

    print "This file is at ", $self->path, "\n";
}

$file->print_info;
# The file is at /etc/hostname

То, что делает метод особенным, — это способ его вызова. Оператор стрелки (->) указывает Perl на то, что мы вызываем метод.

При вызове метода Perl обеспечивает передачу вызывающего объекта в качестве первого аргумента. Вызывающий объект — это красивое название для объекта слева от стрелки. Вызывающий объект может быть именем класса или объектом. Мы также можем передавать дополнительные аргументы в метод:

sub print_info {
    my $self   = shift;
    my $prefix = shift // "This file is at ";

    print $prefix, ", ", $self->path, "\n";
}

$file->print_info("The file is located at ");
# The file is located at /etc/hostname

Атрибуты

Каждый класс может определять свои атрибуты. При создании экземпляра объекта мы присваиваем значения этим атрибутам. Например, каждый объект File имеет путь. Атрибуты иногда называются свойствами.

В Perl нет специального синтаксиса для атрибутов. Под капотом атрибуты часто хранятся в качестве ключей в базовом хеше объекта, но об этом не нужно беспокоиться.

Мы рекомендуем обращаться к атрибутам только через методы-аксессоры. Это методы, которые могут получать или устанавливать значение каждого атрибута. Мы видели это ранее в примере print_info(), который вызывает $self->path.

Вы также можете встретить термины геттер и сеттер. Это два типа аксессоров. Геттер получает значение атрибута, а сеттер устанавливает его. Еще один термин для сеттера — мутатор

Атрибуты обычно определяются как только для чтения или для чтения и записи. Атрибуты только для чтения можно установить только при первом создании объекта, а атрибуты для чтения и записи могут быть изменены в любое время.

Значение атрибута может быть другим объектом. Например, вместо возвращения времени последней модификации как числа, класс File мог бы вернуть объект DateTime, представляющий это значение.

Возможен класс, который не предоставляет никаких публично устанавливаемых атрибутов. Не каждый класс имеет атрибуты и методы.

Полиморфизм

Полиморфизм — это красочный способ сказать, что объекты из двух разных классов разделяют API. Например, у нас могут быть классы File и WebPage, которые оба имеют метод print_content(). Этот метод может производить различные результаты для каждого класса, но у них общий интерфейс.

Хотя два класса могут отличаться по многим параметрам, когда дело доходит до метода print_content(), они одинаковы. Это означает, что мы можем попытаться вызвать метод print_content() на объекте любого из этих классов, и нам не нужно знать, к какому классу принадлежит объект!

Полиморфизм — одна из ключевых концепций объектно-ориентированного проектирования.

Наследование

Наследование позволяет вам создать специализированную версию существующего класса. Наследование позволяет новому классу повторно использовать методы и атрибуты другого класса.

Например, мы можем создать класс File::MP3 , который унаследует от File. Объект File::MP3 — это более конкретный тип File. Все mp3-файлы — файлы, но не все файлы — mp3-файлы.

Мы часто называем отношения наследования родитель-ребенок или родитель-потомок отношениями.

Иногда мы говорим, что ребенок имеет отношение «является» с родительским классом.

File — это суперкласс File::MP3, а File::MP3 — подкласс File.

package File::MP3;

use parent 'File';

Модуль parent — один из способов, предоставляемых Perl, для определения иерархии наследования.

Perl поддерживает множественное наследование, что означает, что класс может наследовать от нескольких родительских классов. Хотя это возможно, мы настоятельно рекомендуем от него отказаться. Обычно, вы можете использовать роли для выполнения всех задач, решаемых с помощью множественного наследования, но более чистым способом.

Обратите внимание, что нет ничего плохого в определении нескольких подклассов одного класса. Это и распространённая, и безопасная практика. Например, мы можем определить классы File::MP3::FixedBitrate и File::MP3::VariableBitrate для различения различных типов файлов mp3.

Переопределение методов и разрешение методов

Наследование позволяет двум классам совместно использовать код. По умолчанию каждый метод родительского класса также доступен в дочернем классе. Дочерний класс может явно переопределить метод родительского класса, предоставив собственное реализацию. Например, если у нас есть объект File::MP3, он имеет метод print_info() из класса File.

my $cage = File::MP3->new(
    path          => 'mp3s/My-Body-Is-a-Cage.mp3',
    content       => $mp3_data,
    last_mod_time => 1304974868,
    title         => 'My Body Is a Cage',
);

$cage->print_info;
# The file is at mp3s/My-Body-Is-a-Cage.mp3

Если мы захотим включить в приветствие название файла mp3, мы можем переопределить метод:

package File::MP3;

use parent 'File';

sub print_info {
    my $self = shift;

    print "This file is at ", $self->path, "\n";
    print "Its title is ", $self->title, "\n";
}

$cage->print_info;
# The file is at mp3s/My-Body-Is-a-Cage.mp3
# Its title is My Body Is a Cage

Процесс определения, какой метод следует использовать, называется разрешением методов. Perl сначала проверяет класс объекта (в данном случае File::MP3). Если этот класс определяет метод, то используется версия метода этого класса. В противном случае Perl проверяет каждый родительский класс по очереди. У класса File::MP3 единственный родитель — File. Если метод не определен в File::MP3, но определен в File, то Perl вызовет метод из класса File.

Если File унаследован от DataSource, а DataSource от Thing, то Perl будет продолжать поиск «по цепочке», если это необходимо.

Возможен явный вызов родительского метода из дочернего:

package File::MP3;

use parent 'File';

sub print_info {
    my $self = shift;

    $self->SUPER::print_info();
    print "Its title is ", $self->title, "\n";
}

Часть SUPER:: указывает Perl на поиск метода print_info() в цепочке наследования класса File::MP3. Найдя родительский класс, реализующий этот метод, Perl вызывает этот метод.

Ранее мы упоминали множественное наследование. Основная проблема с множественным наследованием заключается в том, что оно значительно усложняет разрешение методов. Подробнее см. perlobj.

Инкапсуляция

Инкапсуляция — это концепция, согласно которой объект является непрозрачным. Когда другой разработчик использует ваш класс, ему не нужно знать как он реализован, ему достаточно знать что он делает.

Инкапсуляция важна по нескольким причинам. Во-первых, она позволяет отделить публичный API от закрытой реализации. Это означает, что вы можете изменить реализацию без нарушения API.

Во-вторых, хорошо инкапсулированные классы легче подклассифицировать. В идеале подкласс использует те же API для доступа к данным объекта, что и родительский класс. На практике подклассификация иногда влечёт нарушение инкапсуляции, но хороший API может минимизировать необходимость в этом.

Ранее мы упоминали, что большинство объектов Perl реализованы в виде хэшей. Принцип инкапсуляции говорит нам, что мы не должны полагаться на это. Вместо этого мы должны использовать методы-акцессоры для доступа к данным в этом хэше. Системы объектно-ориентированного программирования, которые мы рекомендуем ниже, все автоматизируют создание методов-акцессоров. Если вы используете одну из них, вам никогда не придётся напрямую обращаться к объекту как к хэшу.

Композиция

В объектно-ориентированном коде мы часто встречаем, что один объект ссылается на другой объект. Это называется композицией или отношением «имеет-а».

Ранее мы упоминали, что метод-аксессор File класса last_mod_time может возвращать объект DateTime. Это идеальный пример композиции. Мы можем пойти ещё дальше и сделать акцессоры path и content возвращающие объекты. Тогда класс File будет составлен из нескольких других объектов.

Роли

Роли — это то, что делает класс, а не то, что он есть. Роли относительно новы для Perl, но стали довольно популярны. Роли применяются к классам. Иногда говорят, что классы используют роли.

Роли — это альтернатива наследованию для обеспечения полиморфизма. Предположим, у нас есть два класса, Radio и Computer. Оба эти класса имеют выключатели включения/выключения. Мы хотим отразить это в наших определениях классов.

Мы могли бы заставить оба класса наследовать от общего родителя, например, Machine, но не все машины имеют переключатели включения/выключения. Мы могли бы создать родительский класс HasOnOffSwitch, но это очень искусственно. Радиоприемники и компьютеры не являются специализациями этого родительского класса. Этот родительский класс — довольно бессмысленное изобретение.

Здесь на помощь приходят роли. Создание роли HasOnOffSwitch и применение её к обоим классам имеет большой смысл. Эта роль определяла бы известный API, например, предоставив методы turn_on() и turn_off().

Perl не имеет встроенного способа выражения ролей. В прошлом люди просто шли на компромисс и использовали множественное наследование. В наши дни есть несколько хороших вариантов на CPAN для использования ролей.

Когда использовать ООП

Объектно-ориентированное программирование не является лучшим решением для каждой проблемы. В «Perl Best Practices» (авторские права 2004, издательство O'Reilly Media, Inc.) Damian Conway предоставляет список критериев для принятия решения о том, подходит ли ООП для вашей задачи:

  • Разрабатываемая система велика или, вероятно, станет большой.

  • Данные могут быть объединены в очевидные структуры, особенно если в каждой структуре много данных.

  • Различные типы данных агрегируются в естественную иерархию, что облегчает использование наследования и полиморфизма.

  • Вы имеете набор данных, к которому применяется множество различных операций.

  • Вам необходимо выполнять одни и те же общие операции над похожими типами данных, но с небольшими вариациями в зависимости от конкретного типа данных, к которому применяются операции.

  • Вероятно, вам придётся добавить новые типы данных позже.

  • Типичные взаимодействия между данными лучше всего представлены операторами.

  • Реализация отдельных компонентов системы, вероятно, будет меняться со временем.

  • Дизайн системы уже объектно-ориентированный.

  • Ваш код модулей будет использоваться большим количеством других программистов.

СИСТЕМЫ PERL OO

Как мы уже упоминали, встроенная система ООП Perl очень минимальна, но и очень гибкая. На протяжении многих лет многие люди разработали системы, которые основаны на встроенной системе Perl, чтобы предоставить больше функций и удобства.

Мы настоятельно рекомендуем использовать одну из этих систем. Даже самые минимальные из них устраняют большое количество повторяющегося кода. В Perl действительно нет веских причин для написания классов с нуля.

Если вас интересуют внутренние механизмы этих систем, см. perlobj.

Moose

Moose позиционируется как «постмодернистская система объектов для Perl 5». Не пугайтесь, метка «постмодернистский» является отсылкой к описанию Лари Perl как «первого постмодернистского компьютерного языка».

Moose предоставляет полную современную систему ООП. Его наибольшее влияние исходит из Common Lisp Object System, но он также заимствует идеи из Smalltalk и нескольких других языков. Moose был создан Стивеном Литтлом и в значительной степени опирается на его работу над дизайном ООП в Raku.

Вот наш пример класса File с использованием Moose.

package File;
use Moose;

has path          => ( is => 'ro' );
has content       => ( is => 'ro' );
has last_mod_time => ( is => 'ro' );

sub print_info {
    my $self = shift;

    print "This file is at ", $self->path, "\n";
}

Moose предоставляет ряд функций:

  • Декларативный синтаксический сахар

    Moose предоставляет слой декларативного «сахара» для определения классов. Этот сахар — это просто набор экспортируемых функций, которые упрощают и делают более удобным объявление того, как работает ваш класс. Это позволяет описывать что является вашим классом, а не как реализовать ваш класс в Perl.

    Подпрограмма has() объявляет атрибут, а Moose автоматически создаёт акцессоры для этих атрибутов. Он также позаботится о создании для вас метода new(). Этот конструктор знает об объявленных вами атрибутах, поэтому вы можете задать их при создании нового объекта File.

  • Встроенные роли

    Moose позволяет определять роли так же, как и классы:

    package HasOnOffSwitch;
    use Moose::Role;
    
    has is_on => (
        is  => 'rw',
        isa => 'Bool',
    );
    
    sub turn_on {
        my $self = shift;
        $self->is_on(1);
    }
    
    sub turn_off {
        my $self = shift;
        $self->is_on(0);
    }
  • Миниатюрная система типов

    В приведенном выше примере вы можете видеть, что мы передали isa => 'Bool' в has() при создании атрибута is_on. Это сообщает Moose, что этот атрибут должен иметь логическое значение. Если мы попытаемся задать ему недопустимое значение, наш код выдаст ошибку.

  • Полный интроспекция и манипулирование

    Встроенные возможности интроспекции Perl довольно ограничены. Moose расширяет их и создаёт полный слой интроспекции для ваших классов. Это позволяет задавать вопросы, например, «какие методы реализует класс File?». Это также позволяет изменять классы программно.

  • Самодостаточность и расширяемость

    Moose описывает себя с помощью собственного API интроспекции. Помимо того, что это интересный трюк, это означает, что вы можете расширить Moose с помощью Moose.

  • Богатый экосистема

    На CPAN есть богатый экосистема расширений Moose в пространстве имен MooseX. Кроме того, многие модули на CPAN уже используют Moose, предоставляя вам множество примеров для обучения.

  • Множество других функций

    Moose — это очень мощный инструмент, и мы не можем охватить все его функции здесь. Мы рекомендуем вам узнать больше, изучив документацию Moose, начиная с Moose::Manual.

Конечно, Moose не идеален.

Moose может замедлить загрузку вашего кода. Moose сам по себе не маленький и выполняет много генерации кода при определении вашего класса. Эта генерация кода означает, что ваш исполняемый код будет быстрым, но вы заплатите за это при первой загрузке модулей.

Эта задержка загрузки может быть проблемой, когда скорость запуска важна, например, в командной строке или в скрипте CGI «plain vanilla», который должен загружаться каждый раз при выполнении.

Прежде чем паниковать, знайте, что многие люди используют Moose для инструментов командной строки и других кодов, чувствительных к стартовому времени. Мы рекомендуем вам сначала опробовать Moose перед беспокойством о скорости запуска.

END_OF_DOCUMENT_MARKER

Moose также имеет несколько зависимостей от других модулей. Большинство из них — небольшие автономные модули, некоторые из которых были выделены из Moose. Moose сам по себе, а также некоторые его зависимости, требуют компилятора. Если вам нужно установить ваше программное обеспечение на систему без компилятора или если наличие любых зависимостей является проблемой, то Moose может вам не подойти.

Moo

Если вы попробуете Moose и обнаружите, что одна из этих проблем препятствует использованию Moose, мы рекомендуем вам рассмотреть Moo далее. Moo реализует подмножество функциональности Moose в более простом пакете. Для большинства реализованных функций API конечного пользователя идентичен API Moose, что означает, что вы можете довольно легко переключиться с Moo на Moose.

Moo не реализует большинство API интроспекции Moose, поэтому при загрузке модулей он часто работает быстрее. Кроме того, ни одна из его зависимостей не требует XS, поэтому его можно установить на машинах без компилятора.

Одним из самых привлекательных свойств Moo является его межплатформенная совместимость с Moose. Когда кто-то пытается использовать API интроспекции Moose для класса или роли Moo, он прозрачно преобразуется в класс или роль Moose. Это упрощает интеграцию кода, использующего Moo, в базу кода Moose и наоборот.

Например, класс Moose может наследовать от класса Moo с помощью extends или использовать роль Moo с помощью with.

Авторы Moose надеются, что однажды Moo можно будет сделать устаревшим, усовершенствовав Moose достаточно, но пока он предоставляет достойную альтернативу Moose.

Class::Accessor

Class::Accessor — полная противоположность Moose. Он предоставляет очень мало функций и не является самодостаточным.

Однако он очень прост, написан на чистом Perl и не имеет зависимостей, не относящихся к ядру. Он также предоставляет API «похожий на Moose» по требованию для поддерживаемых функций.

Несмотря на то, что он не делает многого, он всё же предпочтительнее написания собственных классов с нуля.

Вот наш класс File с Class::Accessor:

package File;
use Class::Accessor 'antlers';

has path          => ( is => 'ro' );
has content       => ( is => 'ro' );
has last_mod_time => ( is => 'ro' );

sub print_info {
    my $self = shift;

    print "This file is at ", $self->path, "\n";
}

Флаг импорта antlers сообщает Class::Accessor, что вы хотите определить свои атрибуты, используя синтаксис, похожий на синтаксис Moose. Единственный параметр, который вы можете передать has, это is. Мы рекомендуем использовать этот синтаксис, похожий на Moose, если вы выбираете Class::Accessor, так как это означает, что у вас будет более плавный путь обновления, если вы впоследствии решите перейти на Moose.

Как и Moose, Class::Accessor генерирует методы доступа и конструктор для вашего класса.

Class::Tiny

И наконец, у нас есть Class::Tiny. Этот модуль полностью оправдывает своё название. Он имеет невероятно минимальный API и абсолютно не зависит от каких-либо современных версий Perl. Тем не менее, мы считаем его намного удобнее, чем написание собственного объектно-ориентированного кода с нуля.

Вот наш класс File ещё раз:

package File;
use Class::Tiny qw( path content last_mod_time );

sub print_info {
    my $self = shift;

    print "This file is at ", $self->path, "\n";
}

Вот и всё!

С помощью Class::Tiny, все методы доступа являются чтением и записью. Он генерирует для вас конструктор, а также методы доступа, которые вы определили.

Вы также можете использовать Class::Tiny::Antlers для синтаксиса, похожего на Moose.

Role::Tiny

Как мы упоминали ранее, роли предоставляют альтернативу наследованию, но Perl не имеет встроенной поддержки ролей. Если вы решите использовать Moose, он поставляется с полноценной реализацией системы ролей. Однако, если вы используете один из наших других рекомендуемых объектно-ориентированных модулей, вы всё ещё можете использовать роли с Role::Tiny

Role::Tiny предоставляет некоторые из тех же функций, что и система ролей Moose, но в гораздо меньшем пакете. Наиболее примечательно, что он не поддерживает никакого объявления атрибутов, поэтому вам придётся это делать вручную. Тем не менее, он полезен и хорошо работает с Class::Accessor и Class::Tiny

Обзор систем ОО

Вот краткий обзор доступных вариантов:

  • Moose

    Moose — максимальный вариант. Он обладает множеством функций, большой экосистемой и активной пользовательской базой. Мы также кратко рассмотрели Moo. Moo — это Moose Lite и разумная альтернатива, когда Moose не подходит для вашего приложения.

  • Class::Accessor

    Class::Accessor делает значительно меньше, чем Moose, и является хорошей альтернативой, если вы считаете Moose чрезмерно сложным. Он существует довольно долго и хорошо протестирован. Он также имеет минимальный режим совместимости Moose, что упрощает переход с Class::Accessor на Moose.

  • Class::Tiny

    Class::Tiny — это абсолютный минимальный вариант. Он не имеет зависимостей и почти не имеет синтаксиса. Это хороший вариант для очень минимальной среды и для быстрого создания чего-либо без необходимости беспокоиться о деталях.

  • Role::Tiny

    Используйте Role::Tiny с Class::Accessor или Class::Tiny, если вы задумываетесь о множественном наследовании. Если вы используете Moose, он поставляется со своей собственной реализацией системы ролей.

Другие системы ОО

На CPAN существует множество других объектно-ориентированных модулей, помимо рассмотренных здесь, и вам, вероятно, придётся столкнуться с одним или несколькими из них, если вы работаете с чужим кодом.

Кроме того, во многих местах код реализует все объектно-ориентированные функции «вручную», используя только встроенные возможности объектно-ориентированного программирования Perl. Если вам нужно поддерживать такой код, вы должны прочитать perlobj, чтобы понять, как именно работают встроенные объектно-ориентированные возможности Perl.

ЗАКЛЮЧЕНИЕ

Как мы уже говорили, минимальная система объектно-ориентированного программирования Perl привела к изобилию систем ОО на CPAN. Хотя вы можете вернуться к основам и написать свои классы вручную, на самом деле нет причин для этого в современных версиях Perl.

Для небольших систем Class::Tiny и Class::Accessor оба предоставляют минимальные объектные системы, которые позаботятся о базовом коде за вас.

Для более крупных проектов Moose предоставляет богатый набор функций, которые позволят вам сосредоточиться на реализации бизнес-логики. Moo предоставляет хорошую альтернативу Moose, когда вам нужно много функций, но требуется более быстрое время компиляции или нужно избежать XS.

Мы рекомендуем вам поэкспериментировать и оценить Moose, Moo, Class::Accessor и Class::Tiny, чтобы выяснить, какая система ОО подходит именно вам.

© 1993–2021 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.34.0/perlootut

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API