to_plain_object 再考

もうちょっと整理。
Plagger::Thing に、以下のようにする。

use Scalar::Util qw( blessed );
sub _to_plain {
    my $val = shift;
    blessed $val && $val->can('to_plain_object')
        ? $val->to_plain_object : $val;
}

sub to_plain_object {
    my $self = shift;
    my $obj  = {};

    my @keys = grep /^[^_]/, keys %$self;
    for my $key( @keys ){
        my $val = $self->{$key};
        if( ref $val eq 'ARRAY' ){
            $val = [ map { _to_plain($_) } @$val ];
        } elsif( ref $key eq 'HASH' ){
            $val = { map { $_ => _to_plain($_) } keys %$val };
        } else {
            $val = _to_plain($val);
        }
        $obj->{$key} = $val;
    }
    $obj;
}

これで Plagger::Thing を継承している Plagger::Feed と Plagger::Entry はどちらも to_plain_object を実装することになる。

  • 余計なオブジェクトが Dump されちゃうのは、_ から始まる名前のだけ無視することに
  • URI のオブジェクトは JSON::Syck で Dump すれば文字列になってくれるので、とりあえずOK
  • Plagger::Date は Plagger::Thing を継承してないので to_plain_object が使えないが……