سؤال

من عند يبارك بيرلوك:

bless REF,CLASSNAME

هذه الوظيفة تخبر Thingy المشار إليها REF هو الآن
كائن في CLASSNAME صفقة.

هل هناك أي طريقة للحصول على بنية غير مجمعة دون نسخ غير ضروري؟

هل كانت مفيدة؟

المحلول

البيانات :: الهيكل :: util

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

نصائح أخرى

البيانات :: الهيكل :: util لديه unbless الوظيفة التي ستفعل ذلك من أجلك. كما يشير إريك ، JSON :: XS لن تقبل عادة المراجع المباركة (على الرغم من أنني أتمنى أن تتجاهل ذلك فقط والتعامل مع بنية البيانات). لا توجد طريقة للتغلب عليها في هذه الحالة.

ولكن فكر في سبب اعتقادك أنك بحاجة إلى إلغاء التعبير عنها. هل تفعل هذا لأحد الفصول الدراسية الخاصة بك أو فئة مختلفة؟ هذا يبدو بشكل مثير للريبة مثل الشيء الخطأ الذي يجب فعله. قد يكون هناك طريقة أفضل.

لديك نفس المشكلة مثل كسر التغليف لأنك يجب أن تفترض أنك تعرف البنية الداخلية للمرجع. إذا كنت ستفعل ذلك ، فيمكنك فقط تجاهل الأشياء الموجهة للكائنات والوصول إلى الهيكل مباشرة.

إذا كنت ستفعل ذلك لفصلك الخاص ، ففكر في توفير طريقة لإرجاع بنية البيانات (والتي لا يجب أن تكون الهيكل الأصلي) بدلاً من تغيير الكائن.

ذكرت في تعليق متابعة أنك قد تقوم بذلك للالتفاف على بعض سلوك مجموعة أدوات القالب. كان لدي هذا الموقف بطريقتين اعتمادًا على الموقف:

  • تمرير البيانات التي تحتاجها فقط إلى القالب بدلاً من الكائن بأكمله.
  • أضف طرقًا إلى الكائن للحصول على البيانات التي تريدها في القالب.

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

إذا كنت تعرف ما الذي يتم دعم كائنك ، فيمكنك القيام بذلك دون استخدام الحزم.

التجزئة

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

مجموعة مصفوفة

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

العددية

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

Acme :: لعنة :)

تحديث: شكرا لك إيفان! أنا خلط الوحدات النمطية. في الواقع أردت أن أعطي رابطًا acme :: اللعنة :))

ملاحظة أنظر أيضا Acme :: العطس :)

PPS ليس له أي فائدة حقيقية ، ولهذا السبب هو Acme::. انظر بوست براين.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top