perlclass
СОДЕРЖАНИЕ
ИМЯ
perlclass - Справочник по синтаксису классов Perl
СИНОПСИС
use v5.38;
use feature 'class';
class My::Example 1.234 {
field $x;
ADJUST {
$x = "Hello, world";
}
method print_message {
say $x;
}
}
My::Example->new->print_message; ОПИСАНИЕ
В этом документе описывается синтаксис class функции Perl, которая предоставляет встроенные ключевые слова, поддерживающие парадигму объектно-ориентированного программирования.
История
Начиная с Perl 5, поддержка объектов вращалась вокруг понятия «благословения» ссылок именем пакета. Затем такую ссылку можно было использовать для вызова подпрограмм из пакета, с которым она была благословлена (или из любого его родителя). Эта система, хотя и простая, была достаточно гибкой, чтобы позволить создание более сложных, разработанных сообществом систем объектно-ориентированного программирования.
Функция класса — это основная реализация синтаксиса класса, знакомого по другим языкам программирования. Это не bless обёртка, а полностью новая система, встроенная непосредственно в интерпретатор Perl.
КЛЮЧЕВЫЕ СЛОВА
Включение class функции позволяет использовать следующие новые ключевые слова в области текущего пакета:
класс
class NAME BLOCK
class NAME VERSION BLOCK
class NAME;
class NAME VERSION; Ключевое слово class объявляет новый пакет, который предназначен быть классом. Все остальные ключевые слова из class функции должны использоваться в области действия этого объявления.
class WithVersion 1.000 {
# class definition goes here
} Классы могут быть объявлены либо в блоке, либо в операторе. Если используется блок, тело блока содержит реализацию класса. Если используется форма оператора, остальная часть файла используется до следующего class или package оператора.
class и package объявления похожи, но классы автоматически получают конструктор под названием new — вам не нужно (и не следует) его писать. Кроме того, в блоке класса вы можете объявлять поля и методы.
поле
field VARIABLE_NAME;
field VARIABLE_NAME = EXPR;
field VARIABLE_NAME : ATTRIBUTES;
field VARIABLE_NAME : ATTRIBUTES = EXPR; Поля — это переменные, видимые в области действия класса — точнее, в блоках "метод" и ADJUST. Каждый экземпляр класса получает своё хранилище полей, независимое от других.
Поле ведет себя как обычная переменная со сферой видимости. Оно имеет префикс и является частным для класса (хотя создание метода доступа сделает его доступным извне). Основное различие заключается в том, что разные экземпляры обращаются к разным значениям в одной и той же области.
class WithFields {
field $scalar = 42;
field @array = qw(this is just an array);
field %hash = (species => 'Martian', planet => 'Mars');
} Поля могут по желанию иметь начальные выражения. Если они присутствуют, выражение будет вычислено внутри конструктора каждого объекта. Во время каждого вычисления выражение может использовать значение любого ранее установленного поля, а также любые другие переменные в области.
class WithACounter {
my $next_count = 1;
field $count = $next_count++;
} В сочетании с атрибутом поля :param выражение по умолчанию может использовать любой из операторов =, //= или ||=. Выражения с использованием = применяются, когда вызывающий не передал соответствующий параметр конструктору вообще. Выражения с использованием //= также применяются, если вызывающий передал параметр, но его значение было неопределенным, а выражения с использованием ||= применяются, если его значение было ложным.
метод
method METHOD_NAME SIGNATURE BLOCK
method METHOD_NAME BLOCK
method SIGNATURE BLOCK
method BLOCK Методы — это подпрограммы, предназначенные для вызова в контексте объектов класса.
Переменная с именем $self, содержащая текущий экземпляр объекта, будет автоматически создана в лексической области действия method.
Методы всегда действуют так, как если бы use feature 'signatures' было активным, но $self не будет появляться в списке аргументов с точки зрения сигнатуры.
class WithMethods {
field $greetings;
ADJUST {
$greetings = "Hello";
}
method greet($name = "someone") {
say "$greetings, $name";
}
} Как и обычные подпрограммы, методы могут быть анонимными:
class AnonMethodFactory {
method get_anon_method {
return method {
return 'this is an anonymous method';
};
}
} АТРИБУТЫ
Конкретные аспекты вышеупомянутых ключевых слов управляются с помощью атрибутов. Все атрибуты начинаются с двоеточия, и один или несколько из них могут быть добавлены после имени элемента, разделённые пробелом.
Атрибуты класса
:isa
Классы могут унаследовать от одного суперкласса, используя атрибут класса :isa.
class Example::Base { ... }
class Example::Subclass :isa(Example::Base) { ... } Унаследованные методы видны и могут быть вызваны. Поля всегда лексические и поэтому не видны по наследованию.
Атрибут :isa может запросить минимальную версию базового класса; он применяется аналогично use - если предоставленная версия слишком низкая, произойдёт ошибка во время компиляции.
class Example::Subclass :isa(Example::Base 2.345) { ... } Атрибут :isa попытается загрузить указанный модуль, если он ещё не загружен.
Атрибуты поля
:param
Скалярное поле с атрибутом :param получит своё значение из именованного параметра, переданного конструктору. По умолчанию параметр будет иметь то же имя, что и поле (без ведущего префикса $), но можно указать другое имя в атрибуте.
field $x :param;
field $y :param(the_y_value); Если нет выражения по умолчанию, параметр является обязательным для конструктора; вызывающий должен передать его, в противном случае будет выброшено исключение. С выражением по умолчанию он становится необязательным.
Атрибуты метода
Пока нет.
ЖИЗНЕННЫЙ ЦИКЛ ОБЪЕКТА
Создание
Каждый объект начинает свою жизнь с вызова конструктора. Конструктор всегда имеет имя new и вызывается как вызов метода имени класса:
my $object = My::Class->new(%arguments); Во время создания поля класса сравниваются с %arguments хэш-таблицей и заполняются, где это возможно.
Настройка
Настройку объекта можно выполнить во время создания для выполнения пользовательского кода. Это делается с помощью ADJUST блоков, которые вызываются в порядке объявления.
Они похожи на BEGIN блоки, которые выполняются во время компиляции пакета. Однако они также имеют доступ к $self лексическим (экземпляру объекта) и всем полям объекта, созданным до этого момента.
Срок жизни
После этапа создания объект готов к использованию.
Использование blessed (Scalar::Util::blessed или builtin::blessed) на объекте вернёт имя класса, в то время как reftype (Scalar::Util::reftype или builtin::reftype) вернёт строку 'OBJECT'.
Удаление
Как и с другими ссылками, когда счётчик ссылок объекта достигнет нуля, он будет автоматически удалён.
TODO
Эта функция всё ещё находится в стадии эксперимента и очень неполна. Следующий список даёт общее представление о видах работ, которые ещё предстоит добавить или изменить:
-
Роли
Некоторый синтаксис для объявления роли (вероятно, ключевое слово
role) и для потребления роли в классе (вероятно, атрибут:does()) -
Параметры для блоков ADJUST
Некоторый синтаксис для объявления, что блок
ADJUSTможет принимать именованные параметры, которые становятся частью API конструктора класса. Это может быть вдохновлено аналогичным планом по добавлению именованных аргументов в сигнатуры подпрограмм.class X { ADJUST (:$alpha, :$beta = 123) { ... } } my $obj = X->new(alpha => 456); -
Блоки ADJUST как истинные блоки
В настоящее время каждый блок ADJUST заключён в собственном CV, который вызывается с полным переключением ENTERSUB. Должно быть возможно использовать ту же механику, которая делает все выражения инициализации поля видимыми внутри одного CV в блоках ADJUST, объединяя их все в один CV на класс. Это ускорит вызов, если у класса больше одного такого блока.
-
Атрибуты генератора доступа
Атрибуты для запроса генерации методов доступа для полей. Вероятно,
:readerи:writer.class X { field $name :reader; }Эквивалентно
class X { field $name; method name { return $name; } } -
Метапрограммирование
Расширение API метапрограммирования (в настоящее время предложено в RFC0022), которое добавляет знание о классах, методах, полях, блоках ADJUST и других подобных деталях класса.
-
Настройка расширения
Способы, которыми модули вне ядра могут взаимодействовать с системой классов, включая возможность предоставлять новые атрибуты класса или поля.
АВТОРЫ
Paul Evans
Bartosz Jarzyna
© 1993–2023 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.38.0/perlclass