Data::Structure::Util tiene una función unbless
que lo hará por usted. Como señala Erik, JSON::XS normalmente no aceptará referencias bendecidas (aunque desearía que simplemente lo ignore y trate con la estructura de datos). No hay forma de evitarlo en este caso.
Pero considere por qué cree que necesita deshacerlo. ¿Estás haciendo esto para una de tus clases o una clase diferente? Esto suena sospechosamente a The Wrong Thing To Do. Puede haber una mejor manera.
Tiene el mismo problema que romper la encapsulación porque tiene que asumir que sabe cuál es la estructura interna de la referencia. Si va a hacer eso, puede simplemente ignorar las cosas orientadas a objetos y acceder a la estructura directamente.
Si va a hacer esto para su propia clase, considere proporcionar un método para devolver una estructura de datos (que no tiene que ser la estructura original) en lugar de cambiar el objeto.
Mencione en un comentario de seguimiento que podría estar haciendo esto para evitar el comportamiento de algunos Toolkit de plantillas. Tuve esta situación de dos maneras dependiendo de la situación:
- Solo pase los datos que necesita a la plantilla en lugar de todo el objeto.
- Agregue métodos al objeto para obtener los datos que desea en la plantilla.
Perl es DWIM, pero TT es incluso DWIMmier, lo que a veces es desafortunado.
Aquí un corte rápido cuando defino un TO_JSON
en UNIVERSAL
por lo que se aplica a todos los objetos. Realiza una copia profunda, la deshace y devuelve la estructura de datos.
#!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);
Ver también http://www.perlmonks.org/?node_id=183348 –
@Ether: Por ejemplo, Template :: Toolkit. El operador punto ''.'' se usa para acceder a listas y hashes o para llamar a métodos de objetos. TT siempre intenta primero un método de objeto. –
FWIW Necesito 'no disponible' porque' YAML :: Any :: Dump() 'conservará la naturaleza bendecida de un objeto, no quiero almacenar eso, pero a veces los hashes de datos que estoy descargando son bendecidos. También 'Moose-> new' es muy quisquilloso y no tomará un bendito hashref para una discusión. – Schwern