Moose (Perl): Можно ли использовать% $ object для получения представления данных объекта для сериализации? - PullRequest
4 голосов
/ 04 июня 2011

Я часто использую Moose, чтобы убедиться, что мои данные имеют подходящие значения по умолчанию, как здесь:

package Bla;
use Moose;
has eins => is => 'ro', isa => 'Int';
has zwei => is => 'ro', isa => 'Int', default => 2;
no Moose; __PACKAGE__->meta->make_immutable;

package main;
use v5.10;
use Data::Dumper;
use URI;

my $bla = Bla->new( eins => 77 );
my $bl2 = Bla->new;
print Dumper $bla, $bl2;
say join "\t", %$bla;
say join "\t", %$bl2;

my $u = URI->new( 'http://www.example.com/ws' );
$u->query_form( %$bla );
say $u;
$u->query_form( %$bl2 );
say $u;

До тех пор, пока у такого типа контейнера данных нет ссылочных элементов (следовательно, нет вложенности), можете ли вы сказать, что это нормально или рекомендуется просто использовать хеш-таблицу объектов, как в %$object, если вы хотите получить необработанные данные, скажем, в качестве инициализатора для сериализации через URI->query_form илипохожие методы?Или есть лучший способ достичь этого, который встроен в Moose?

ОБНОВЛЕНИЕ

Похоже, я вывел людей на неверные пути, отбросив это маленькое слово сериализация в строках выше, в заголовке и даже в тегах.Обратите внимание, что я не заинтересован в поиске сериализаторов.В моем примере модуль URI является сериализатором.Вопрос в том, как получить данные для подачи URI->query_form (или любой другой сериализатор, который я мог бы попробовать).Поэтому я хочу знать, можно ли для данного объекта Moose $object захватывать данные (ключи и значения или, если вы предпочитаете, имена и значения свойств), просто разыменовывая ссылку на объект, как в %$object?Это будет работать, если мой опыт, накопленный до сих пор, является чем-то необходимым, если объекты не содержат никаких ссылочных значений (таких как ссылки на массивы, другие объекты и т. Д.) И - в чем я не уверен - Moose выигралне используйте ссылку на экземпляр для хранения собственных данных, таких как __MOOSE_WHATNOT => $funky_moose_addon.Так может ли Moose использовать ссылку на экземпляр для хранения некоторых своих собственных данных, или это исключено проектом?

UPDATE 2

Чтобы ответить на вопрос в заголовке:

Нет, это не нормально , чтобы использовать %$object для получения данных объекта Moose, даже если он не содержит никаких ссылочных значений, поэтому вы получите копиюстроки и числа, составляющие $object.Это не хорошо, потому что это нарушает инкапсуляцию.Это может даже привести к ошибке во время выполнения, потому что, хотя хэш является структурой данных по умолчанию для формирования базы объекта Moose, нет гарантии, что это всегда будет хеш, а на самом деле это может быть что-то другое.

Вместо этого следует использовать MooseX::Storage, что обеспечит объект методом pack.

Ответы [ 2 ]

5 голосов
/ 05 июня 2011

Как сказал Джира, каноническим способом было бы использовать MooseX::Storage.Проблема с объектом% $ состоит в том, что, хотя хранилище по умолчанию для экземпляра объекта Moose является благословенным хэшем, Moose не дает никаких официальных обещаний, что это всегда так.Например, MooseX :: GlobRef, MooseX :: NonMoose, MooseX :: InsideOut допускают альтернативные структуры экземпляров.

Пакет, такой как MooseX :: Storage, использует MOP для опроса метаобъекта экземпляра и правильной сериализации структуры данных.Конечно, вы можете сделать это вручную, просканировав Moose :: Meta :: Class, который стоит за каждым объектом Moose, но, честно говоря, MooseX::Storage хорошо написан и очень стабилен на данный момент.

Стандартное использованиебыть:

package Class {
     use Moose;
     use MooseX::Storage;
     with Storage();
     ...
}

my $o = Class->new(...)
my $u = URI->new( 'http://www.example.com/ws' );
$u->query_form( $o->pack );
5 голосов
/ 04 июня 2011

Moose "родным" способом будет использовать MooseX :: Storage набор классов.

...