Pregunta

perldoc -f bendiga :

  

bless REF,CLASSNAME

     

Esta función le dice a la manivela de la que hace referencia REF que ahora es
          un objeto en el paquete CLASSNAME.

¿Hay alguna manera de obtener una estructura sin bendecir sin copiar innecesario?

¿Fue útil?

Solución

de datos :: Estructura :: Util

  

unbless($ref)

     

Eliminar la bendición de cualquier objetos encontrados dentro de la estructura de datos pasado.

#!/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;

Salida:

My : 237356
HASH : 237356

Otros consejos

de datos :: Estructura :: Util tiene una función unbless que lo hará para ti. Como señala Erik, JSON :: XS normalmente no aceptará referencias bendecido (aunque me gustaría que simplemente ignorar eso y trato con la estructura de datos). No hay manera de evitarlo en este caso.

Pero considere qué es lo que cree necesario que unbless ella. ¿Estás haciendo esto para una de sus propias clases o una clase diferente? Esto suena sospechosamente a la Cosa del mal Para Do. Puede haber una mejor manera.

Usted tiene el mismo problema que romper la encapsulación porque hay que asumir que usted sabe lo que la estructura interna de la referencia es. Si se va a hacer eso, puede simplemente ignorar la materia orientada a objetos y la estructura de acceso directamente.

Si usted va a hacer esto para su propia clase, considere la posibilidad de proporcionar un método para devolver una estructura de datos (que no tiene por qué ser la estructura original) en lugar de cambiar el objeto.

Usted menciona en un comentario de seguimiento que podría estar haciendo esto para obtener alrededor de un comportamiento Template Toolkit. Tenía esta situación de dos maneras dependiendo de la situación:

  • Sólo pasar los datos que necesita para la plantilla en lugar de todo el objeto.
  • Añadir métodos para el objeto de obtener los datos que desee en la plantilla.

Perl es DWIM, pero es aún TT DWIMmier, lo cual es lamentable veces.


Aquí hay un corte rápido cuando defino un TO_JSON en UNIVERSAL por lo que se aplica a todos los objetos. Se hace una copia profunda, unblesses, 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 );

Si usted sabe lo que su objeto está respaldado por, usted podría hacer esto sin el uso de paquetes.

Hash

$obj = bless {}, 'Obj';
print ref $obj, "\n";
$obj = { %$obj };
print ref $obj, "\n";

Array

$obj = bless [], 'Obj';
print ref $obj , "\n";
$obj = [ @$obj ];
print ref $obj, "\n";

Scalar

$obj = bless \$a, "Obj";
print ref $obj, "\n";
$obj = \${ $$obj };
print ref $obj, "\n";

Acme :: maldición :)

Actualización: Gracias, Ivan! Me confundí módulos. En realidad quería dar un enlace a Acme :: Maldita :))

P. . S Acme :: estornudo :)

P. P. S. No tiene ningún uso real, es por eso que es Acme::. Ver post de Brian.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top