簡體   English   中英

將數據結構轉換為perl對象(模塊推薦)

[英]Turn data structures into perl objects (module recommendation)

我有一個任意的數據結構,我想把它當作一個對象。 我將此作為REST應用程序的響應。 以下示例。 CPAN上有一些模塊可以做到這一點。 Data :: Object看起來對我來說最好,但它是2011年的最后一次更新。我錯過了什么嗎? 是否有一種簡單的Moose方法可以做到這一點? 謝謝!

$o=$class->new($response);
$s=$o->success;
@i=$o->items;
{
    'success' => bless( do{\(my $o = 1)}, 'JSON::XS::Boolean' ),
    'requestNumber' => 5,
    'itemsCount' => 1,
    'action' => 'search.json',
    'totalResults' => 161,
    'items' => [
        {
            'link' => 'http://europeana.eu/api//v2/record/15503/E627F23EF13FA8E6584AF8706A95DB85908413BE.json?wskey=NpXXXX',
            'provider' => [
                'Kulturpool'
            ],
            'europeanaCollectionName' => [
                '15503_Ag_AT_Kulturpool_khm_fs'
            ],
            # more fields omitted
        }
    ],
    'apikey' => 'Npxxxx'
}; 

雖然我不喜歡使用它,但定義AUTOLOAD子例程是一種動態創建任意類的方法。 我使用它已經有一段時間了,但看起來應該是這樣的:

package Local::Foo;

sub new {
    my $class = shift;

    my $self = {};
    bless $self, $class;
    return $self;
}

sub AUTOLOAD {
    my $self = shift;
    my $value = shift;

    our $AUTOLOAD;
    (my $method = $AUTOLOAD) = s/.*:://;
    if ( defined $value ) {
        $self->{$method} = $value;
    }
    return $self->{$method};
}

這個類Local::Foo有無數的方法。 例如,如果我說

$foo->bar("fubar");

這將是:

$foo->{bar} = "foobar";

如果我叫$foo->bar; ,它將返回$foo->{bar};的值$foo->{bar};

您可能希望限制方法的樣式及其值。 例如,有了這個:

$foo->BAR;
$foo->Bar;
$foo->bar;

都是三種有效且完全不同的方法。 你可能想要一些東西來確保你的方法匹配一個特定的模式(即,它們都是小寫的,或者第一個字母是大寫的,其余的是小寫的。你可能想確保它們以字母開頭,所以, $foo->23diba;不是有效的方法。

一個小問題:一旦定義了AUTOLOAD子程序,您也可以定義DESTROY子程序。 Perl在對象被​​銷毀之前調用DESTROY子例程。 如果$AUTOLOAD =~ /.*::DESTROY$/你需要處理這個問題。 您可能需要添加:

return if $AUTOLOAD =~ /.*::DESTROY$/;

AUTOLOAD子程序中的某個位置,因此在調用DESTROY時不會意外地執行某些操作。 請記住,只要一個類對象超出范圍(如果存在),就會自動調用它,而使用AUTOLOAD ,無論如何都會定義一個。

這是一個例子:

use strict;

package Foo; 

#define a simple Foo class with 3 properties
use base qw(Class::Accessor);
Foo->mk_accessors(qw(name role salary));


package main;
#define a perl hash with the same keys
my $hr = {'name'=>'john doe', 'role'=>'admin', 'salary'=>2500 };

#bless the object
my $obj = bless $hr, 'Foo';

print $obj->name, "\n"; #<-- prints: john doe

我並不是說這一定是一個好主意,是實現這個想法的最佳方式,或者是免費的。 我從未嘗試過,直到15分鍾前。 但它很有趣而且很簡潔,所以 -

#!/usr/bin/env perl
BEGIN {
    package Role::AutoVacca;
    use Moo::Role;
    use Scalar::Util "blessed";
    sub BUILD {
        my $self = shift;
        for my $attr ( grep /\A[^_]/, keys %{$self} )
        {
            Method::Generate::Accessor
                ->generate_method( blessed($self),
                                   $attr,
                                   { is => "rw" } );
        }
    }

    package Fakey;
    use Moo;
    with "Role::AutoVacca";
}

my $fake = Fakey->new({
    success => bless( do{\(my $o = 1)}, "JSON::XS::Boolean" ),
    items => [ { link => "http://europeana.eu/o/haipi",
                 provider => [ "mememememe" ] } ],
    apikey => "3k437" });

print "I CAN HAZ KEE? ", $fake->apikey, $/;
print "IZ GUD? ", $fake->success ? "YAH" : "ONOES", $/;
print "WUT DIZZYING? ", $fake->items, $/;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM