木曜日, 11月 30, 2006

[Perl]YAMLでblessさせる

YAMLファイル内に!perl/packageというタグを記述することでファイルロード時に値をblessさせることができます。
例えばこんなかんじで

#!/usr/local/bin/perl
use strict;

package Model::Book;
use base 'Class::Accessor';

my @accessors = qw(author title publisher);
__PACKAGE__->mk_accessors(@accessors);

sub as_string {
my $self = shift;
return join "\n", map {"$_: " . $self->$_()} @accessors;
}

package main;
use YAML::Syck;
use Data::Dumper;

my $data = do { local $/; <DATA>};
my $yml = YAML::Syck::Load($data);

print Dumper($yml);
for my $model (@{$yml->{models}}) {
print "############\n";
print $model->as_string . "\n";
}

__END__
models:
- !perl/Model::Book
author: Damian Conway
title: Perl Best Practice
publisher: O'REILLY
- !perl/Model::Book
author: Larry Wall
title: Programming Perl
publisher: O'REILLY


としておくと


$VAR1 = {
'models' => [
bless( {
'publisher' => 'O\'REILLY',
'title' => 'Perl Best Practice',
'author' => 'Damian Conway'
}, 'Model::Book' ),
bless( {
'publisher' => 'O\'REILLY',
'title' => 'Programming Perl',
'author' => 'Larry Wall'
}, 'Model::Book' )
]
};
############
author: Damian Conway
title: Perl Best Practice
publisher: O'REILLY
############
author: Larry Wall
title: Programming Perl
publisher: O'REILLY


のような結果になります。

これを使えば引数にオブジェクトをとるプラグインなんかも容易にYAMLでDIできるなぁと思ったのですが、以下のような問題が発覚しました。

  1. newなどの初期化メソッドを一切呼んでくれない
  2. 単にblessするだけでuseすらしてくれない

これらのことから結局はなんらかのフレームワークに頼らないと上手く実現できなさそう。。。Rubyの場合はYAML for Rubyにもあるようにいろいろできるみたいですが、PerlのYAMLサポートはいまいち充分ではないようです。なんかやり方あるのかなぁ。。。


0 件のコメント: