Data :: Structure :: Util имеет функцию unbless
, которая сделает это за вас. Как указывает Эрик, JSON :: XS обычно не принимает благословенные ссылки (хотя я хотел бы, чтобы он просто игнорировал это и имел дело со структурой данных). В этом случае нет пути.
Но подумайте, почему, по вашему мнению, вам нужно его снять. Вы делаете это для одного из ваших собственных классов или другого класса? Это звучит подозрительно, как The Wrong Thing To Do. Там может быть лучший способ.
У вас та же проблема, что и при нарушении инкапсуляции, поскольку вы должны предположить, что знаете, какова внутренняя структура ссылки. Если вы собираетесь это сделать, вы можете просто проигнорировать объектно-ориентированные вещи и получить прямой доступ к структуре.
Если вы собираетесь сделать это для своего собственного класса, рассмотрите возможность предоставления метода для возврата структуры данных (которая не должна быть исходной структурой) вместо изменения объекта.
В последующем комментарии вы упоминаете, что, возможно, делаете это, чтобы обойти поведение Template Toolkit. У меня была эта ситуация двумя способами в зависимости от ситуации:
- В шаблон передаются только необходимые данные, а не весь объект.
- Добавьте методы к объекту, чтобы получить необходимые данные в шаблоне.
Perl - это DWIM, а TT - даже DWIMmier, что иногда бывает неудачно.
Вот быстрый взлом, где я определяю TO_JSON
в UNIVERSAL
, чтобы он применялся ко всем объектам. Он делает глубокую копию, разбирает ее и возвращает структуру данных.
#!perl
use v5.10;
sub UNIVERSAL::TO_JSON {
my( $self ) = shift;
use Storable qw(dclone);
use Data::Structure::Util qw(unbless);
my $clone = unbless( dclone( $self ) );
$clone;
}
my $data = bless {
foo => bless( [], 'Local::Array' ),
quack => bless( {
map { $_ => bless [$_, $_**2], 'Local::Array' }
grep { is_prime } 1 .. 10
}, 'Local::Hash' ),
}, 'Local::Hash';
use JSON::XS;
my $jsonner = JSON::XS->new->pretty->convert_blessed(1);
say $jsonner->encode( $data );