Frage

perldoc -f segnen :

  

bless REF,CLASSNAME

     

Diese Funktion teilt das Dingen von REF verwiesen, dass es jetzt ist
          ein Objekt im CLASSNAME Paket.

Gibt es eine Möglichkeit, um eine unblessed Struktur ohne unnötiges Kopieren zu erhalten?

War es hilfreich?

Lösung

Data :: Struktur :: Util

  

unbless($ref)

     

Nehmen Sie den Segen von allen Objekten innerhalb der übergebenen Datenstruktur gefunden.

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

Ausgabe:

My : 237356
HASH : 237356

Andere Tipps

Data :: Struktur :: Util eine unbless Funktion hat, die es tun für Sie. Wie Erik weist darauf hin, JSON :: XS normalerweise nicht gesegnet Referenzen akzeptieren (obwohl ich wünschte, es würde einfach ignorieren das und befassen sich mit der Datenstruktur). Es gibt keinen Weg, um es in diesem Fall.

Aber darüber nachdenken, warum denken Sie, Sie unbless brauchen. Tun Sie dies für einen Ihrer eigenen Klassen oder einer anderen Klasse? Das klingt verdächtig nach dem falschen Sache zu Do. Es könnte ein besserer Weg geben.

Sie haben das gleiche Problem wie Verkapselung zu brechen, weil Sie müssen davon ausgehen, dass Sie wissen, was die innere Struktur der Referenz. Wenn Sie das tun werden, können Sie einfach ignorieren die objektorientierte Sachen und den Zugang der Struktur direkt an.

Wenn Sie vorhaben, dies für die eigene Klasse tun, denken Sie daran, ein Verfahren, eine Datenstruktur zurück (die nicht die ursprüngliche Struktur sein muss), statt das Objekt zu ändern.

erwähnen Sie in einem Follow-up-Kommentar, dass Sie dies tun könnten einige Template Toolkit Verhalten zu umgehen. Ich hatte diese Situation auf zwei Arten je nach Situation:

  • Es werden nur die Daten übergeben Sie anstelle des gesamten Objekts an der Vorlage benötigen.
  • Fügen Sie Methoden für das Objekt die Daten erhalten Sie in der Vorlage werden soll.

Perl ist DWIM, aber TT ist auch DWIMmier, die unglückliche manchmal ist.


Hier ist eine schnelle Hack, wo ich eine TO_JSON in UNIVERSAL definieren, so dass es für alle Objekte gilt. Es macht eine tiefe Kopie, unblesses es und gibt die Datenstruktur.

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

Wenn Sie wissen, was Ihre Aufgabe durch gesichert ist, könnten Sie dies tun, ohne Pakete zu verwenden.

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 :: Fluch :)

Update: Danke, Ivan! I gemischt Module. Eigentlich wollte ich einen Link geben Gipfel :: Verdammt :))

P. . S finden Sie unter Gipfel :: Sneeze :)

P. P. S. Es hat keine wirkliche Verwendung, das ist, warum es Acme::. Siehe Brians Post.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top