bless REF,CLASSNAME
Эта функция говорит штуку, на которую ссылаются
REF
то, что это теперь
объект вCLASSNAME
пакет.
Есть ли какой-либо способ получить несчастную структуру без ненужного копирования?
unbless ($ ref)
Удалите благословение с любых объектов, найденных в переданной структуре данных.
#!/usr/bin/perl
use strict; use warnings;
use Scalar::Util qw( refaddr );
use Data::Structure::Util qw( unbless );
my $x = bless { a => 1, b => 2 } => 'My';
printf "%s : %s\n", ref $x, refaddr $x;
unbless $x;
printf "%s : %s\n", ref $x, refaddr $x;
Вывод:
My : 237356 HASH : 237356
Обновление: Спасибо, Иван! Я перепутал модули. Собственно хотел дать ссылку на Acme :: Damn :))
P. S. См. Также Acme :: Sneeze :)
P. P. S. Это бесполезно, поэтому это Acme ::
. См. Сообщение Брайана.
Data::Structure::Util имеет функцию unbless
, которая сделает это за вас. Как отмечает Эрик, JSON::XS обычно не принимает благословенные ссылки (хотя я бы хотел, чтобы он просто игнорировал это и работал со структурой данных). В данном случае обойти это невозможно.
Но подумайте, почему вы считаете, что вам нужно снять благословение. Вы делаете это для одного из своих классов или для другого класса? Это звучит подозрительно похоже на "Неправильный поступок". Возможно, есть лучший способ.
У вас возникает та же проблема, что и при нарушении инкапсуляции, потому что вы должны предположить, что знаете внутреннюю структуру ссылки. Если вы собираетесь сделать это, вы можете просто проигнорировать объектно-ориентированные вещи и получить доступ к структуре напрямую.
Если вы собираетесь сделать это для своего класса, подумайте о том, чтобы предоставить метод для возврата структуры данных (которая не обязательно должна быть исходной структурой) вместо изменения объекта.
В последующем комментарии вы упомянули, что, возможно, вы делаете это, чтобы обойти некоторое поведение 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 );