Text::Hatena::PPT の action への項目マージ方法

Text::Hatena::PPT の action プロパティへ、複数の項目を追加したり書き換えるには次のように記述することができます。このプロパティは bless されていない単なるハッシュリファレンスですけど、一種の has-a の継承と上書きになっています。

package Hoge;
use base qw(Text::Hatena::PPT);   # これは is-a の継承

sub initialize {
    my $self = shift;
    $self->SUPER::initialize(@_);
    $self->action(                # こっちは has-a の継承
        %{$self->action},
        spre => { # 上書き
            startstring => qq{<pre class="code">},
            endstring   => qq{</pre>\n}
        },
        h4 => { # 追加
            startstring => qq{<h4 class="subsection_header">},
            endstring   => qq{</h4>\n}
        }
    );
}

説明

perl でハッシュ %H0 へ %H1 をマージする書き方の一つにこんなのがあります。直感的で良いですね。

%H0 = (%H0, %H1);

action へのマージはこれを使ってみました。

余談

では、ついでながら、リファレンスの場合はどうなるのでしょうか。以下のように、デリファレンスして代入してやれば、まったく同じ動作をします。さらに注目するべきは、リファレンスされている本体に期待通りマージされていることです。本体は廃棄&再割り当てされることなくマージがおこなわれます。

my $h = {H => 1, He => 3}; # He 間違えた
print "$h\n";      # HASH(0x465408)
%$h = (%$h, He => 2, Li => 3); # 修正して Li 追加
print "$h\n";      # HASH(0x465408) で変化無し
print join " ", %$h, "\n"; # H 1 He 2 Li 3

それなら、bless した場合にどうなるかもチェックしてみましょう。

my $h0 = bless {H => 1, He => 3}, &#39;Hoge&#39;;
print "$h0\n";      # Hoge=HASH(0x465408)
%$h0 = (%$h0, He => 2, Li => 3);
print "$h0\n";      # Hoge=HASH(0x465408) で変化無し
print join " ", %$h, "\n"; # H 1 He 2 Li 3

本体だけでなくて、クラス名も受け継いでいます。オブジェクトのプロパティ自身の has-a の継承と上書きに、このやりかたが使えることがわかると思います。