もうちょっと整理。
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 を実装することになる。