Цель состоит в том, чтобы увидеть инкапсулированные данные, как я и делал последние 26 лет.
use 5.040;
use strictures;
use experimental 'class';
class Foo {
field @member = qw(e r t);
}
my $foo = Foo->new;
# use Data::Dumper qw(Dumper);
# say Dumper $foo;
# cannot handle ref type 16
# use DDS; DumpLex $foo;
# _dump_rv() can't handle 'OBJECT' objects yet
# use Data::Dx; Dx $foo;
# Can't handle OBJECT data
# use DDP; p $foo;
# Foo {
# public methods (1): new
# private methods (0)
# internals: (opaque object)
# }
# ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑





Если вы хотите использовать class, который специально разработан так, чтобы вы не могли заглянуть в его внутренности, вы также не сможете сбрасывать его с помощью внешних модулей. Вам придется что-то добавить в класс, чтобы выгрузить вещи, а это большая дополнительная работа. В целом я не думаю, что class — это хорошая идея, и такого рода препятствие на пути практического развития — одна из причин, по которой я так считаю.
Я также рассматриваю отсутствие интерфейса проверки как препятствие для использования функции «класса» в моих проектах.
Однако универсальная поддержка отладчиками и дамперами не является невозможной. Ему просто придется подождать, пока не станет доступен протокол метаобъектов (MOP) для функции «класс». Конечно, после этого еще предстоит поработать над его использованием.
Для модуля CPAN Object::Pad , который является своего рода испытательным стендом для этой функции, имеется MOP и базовая поддержка Data::Printer . Также есть доказательство концепции, как проверять объекты Object::Pad с помощью отладчика Perl.
Из доступных модулей Data::Dumper не является хорошим кандидатом для проверки данных инкапсулированного класса: по широко распространенной привычке он предоставляет действительный код Perl, который может конструировать данные. Однако это обычно невозможно ни с объектами типа «класс», ни с объектами Object::Pad. Модулям, которые не связаны ожиданием выполнения туда и обратно, просто необходимо реализовать MOP.
Извините, если это прозвучало неправильно: я не хотел подразумевать неправильное использование или странность. Data::Dumper и две из перечисленных альтернатив, DDS и Data::Dx , используют код Perl в качестве выходного формата. Внутренности объектов «класса» не могут отображаться как действительный код Perl. Однако людям не обязательно нужен код Perl, чтобы увидеть инкапсулированные данные. Вот почему такие модули, как DDP, которые не выводят код Perl, лучше подходят для решения проблемы ОП.
Пакет Tuple::Munge на CPAN может вам помочь.
use v5.38;
sub tuple_to_aref ( $t ) {
use Tuple::Munge ();
use experimental 'builtin';
use builtin 'blessed';
my $len = Tuple::Munge::tuple_length($t);
my $aref = [ map Tuple::Munge::tuple_slot($t, $_-1), 1 .. $len ];
if ( my $class = blessed $t ) {
return bless( $aref, "TUPLE_TO_ARRAY::$class" );
}
return $aref;
}
use experimental 'class';
use Data::Dumper;
class My::Class {
field $x;
ADJUST {
$x = 'Foobar';
}
}
my $object = My::Class->new;
print Dumper( tuple_to_aref( $object ) );
Пример вывода:
$VAR1 = bless( [
\'Foobar'
], 'TUPLE_TO_ARRAY::My::Class' );
Это дает вам ссылку на массив, но не сообщает, какому полю принадлежит элемент массива. Это лучше, чем ничего, но для объекта средней сложности это неудовлетворительно. Вы можете рассмотреть возможность демонстрации результатов вашей программы, чтобы люди могли видеть, что они на самом деле получают.
Не указано, к какому полю принадлежит элемент массива, это то, что он имеет общего с любыми объектами Perl, не имеющими хеш-ссылок, например, с объектами, основанными на благословенных ссылках на массив. Однако добавил образец вывода.
Если я решу использовать ссылку на массив в качестве основы для моего объекта, я могу выбрать порядок элементов. И люди могут проверить источник, чтобы увидеть, что и куда пошло. С новыми объектами не так уж и много.
Data::Dumper выводит Perl-код потому, что он это делает, а не из-за привычки или какого-то странного способа, которым люди злоупотребляют. Но несмотря на это, Data::Dumper довольно хорошо служил людям на протяжении десятилетий, отсюда и вопрос.