3

私は任意のデータ構造を持っており、それをオブジェクトとして扱いたいと思っています。これを 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'
}; 
4

3 に答える 3

1

私はそれを使うのは好きではありませんが、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;

3 つすべてが有効で、まったく異なる方法です。メソッドが特定のパターンに一致することを確認する何かが必要になる場合があります (つまり、すべて小文字である、または最初の文字が大文字で残りが小文字であるなど)。おそらく、メソッドが文字で始まることを確認したいので、そうで$foo->23diba;はありません有効な方法。

1 つの小さな問題: サブルーチンを定義すると、AUTOLOADサブルーチンも定義しDESTROYます。Perl はDESTROY、オブジェクトが破棄される前にサブルーチンを呼び出します。その場合も問題を処理する必要があり$AUTOLOAD =~ /.*::DESTROY$/ます。以下を追加する必要がある場合があります。

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

サブルーチンのどこかにあるAUTOLOADので、 が呼び出されたときに誤って何かを実行することはありませんDESTROY。クラスオブジェクトが存在する場合、クラスオブジェクトがスコープ外になるたびに自動的に呼び出されることを覚えておいてくださいAUTOLOAD

于 2013-04-26T04:45:33.687 に答える
0

これが必ずしも良いアイデアだとか、そのアイデアを実行するための最良の方法だとか、問題がないなどと言っているわけではありません。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, $/;
于 2013-04-25T22:33:36.910 に答える
0

これは例です:

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
于 2013-04-25T19:01:51.490 に答える