Publish::JSON との関連で

miyagawaさんと先週ちょっと話してそのままになってた。
やはり、単に Plagger::Feed を丸ごと Dump するだけだと余計なオブジェクトが入ったりして、あまり嬉しくない。

Feed, Entry, Enclosure あたりが to_plain_object のようなメソッドを実装して、bless されてない素のハッシュリファレンスなり文字列なりを返すように。Publish::JSON はそっちを Dump する、という風にしたほうがいいのかな。
# メソッド名が toJson だと、他の Serializer を使う場合に混乱しそう

試しに、Plagger::Feed に to_plain_object を実装してみるとこんな感じか。

  • bless されていて、かつ to_plain_object を実装していたら実行した結果を使う
  • そうでなければそのまま
  • ただし
    • link, url は URI のオブジェクトなので文字列化
    • updated も Plagger::Date なので文字列化
use Scalar::Util qw(blessed);
sub to_plain_object {
    my $self = shift;
    my $obj  = {};

    for my $key( qw( description language author type ) ) {
        $obj->{$key} = blessed $self->{$key} && $self->{$key}->can('to_plain_object')
            ? $self->{$key}->to_plain_object : $self->{$key};
    }

    for my $key( qw( link url updated ) ){
        $obj->{$key} = blessed $self->{$key} && $self->{$key}->can('to_plain_object')
            ? $self->{$key}->to_plain_object : $self->{$key}. '';
    }

    for my $key( qw( tags entries ) ){
        $obj->{$key} = [
            map {
                blessed $_ && $_->can('to_plain_object') ? $_->to_plain_object : $_
            } @{$self->{$key}}
        ];
    }

    $obj->{meta} = {
        map {
            $_ => (
                blessed $self->{meta}->{$_} && $self->{meta}->{$_}->can('to_plain_object')
                    ? $self->{meta}->{$_}->to_plain_object : $self->{meta}->{$_}
            )
        } keys %{$self->{meta}}
    };

    $obj;
}