Hatena::ブログ(Diary)

Scrapcode@はてなダイアリー このページをアンテナに追加 RSSフィード

2010-03-19

CGI::Application::Plugin::Config::YAMLでハマるかもしれないこと

CGI::Application::Plugin::Config::YAML(以降、CAP::Config::YAMLと表記)で以前ハマったのにすっかり忘れていて、またハマったのでメモ。

複数ファイルを読み込んだ場合、引数無しのconfig_paramは期待する値を返さない

CAP::Config::YAMLは、以下のようにして複数のYAMLファイルを読み込むことができます。

# ここで $self は CGI::Applicationを継承して作ったアプリケーションクラスのオブジェクトのこと

# YAMLファイル設定
$self->config_file( 'config.yaml' );

# 追加読み込み
$self->config_read( 'aaa.yaml' );
$self->config_read( 'bbb.yaml' );

トップレベルのキーが重複する場合は、後勝ちで上書きになります。重複しない場合は単純に追加されます。

次に、config_paramメソッドで全てのデータハッシュを取得するために、引数無しで呼び出します。

my $hash = $self->config_param;

が、これではダメなのです。これで取得できるのは、config_fileメソッドで指定したファイルのデータのみなのです。

config_paramメソッドを引数無しで呼び出した時は内部でget_hashメソッドが呼び出されるのですが、このget_hashメソッドではconfig_fileメソッドで指定したYAMLファイルのみを再度読み込んで解析した結果を返しているのです。

sub get_hash {
    my $self = shift;
    my $yaml;

    open(FH,'<',$self->config_file) or die "Can't open $self->config_file; $!\n";
    while (my $line = <FH>) {
        next if ($line =~ /^\-{3,}/);
        next if ($line =~ /^#/);
        next if ($line =~ /^$/);
        $yaml .= $line;
    }
    close(FH);

    my $tmpyaml = YAML::Load($yaml);
    return $tmpyaml;
}

仕方が無いので、内部のConfig::YAMLオブジェクトを直接参照することにします。

my $hash = $self->config;
# この場合、ref $hash が Config::YAMLになってしまう

オブジェクトを直接参照するのが気持ち悪い場合は、オブジェクトハッシュを一旦デリファレンスしておきます。

my $hash = { %{ $self->config } };
# この場合、ref $hash は HASH になる

Config::YAMLが内部で使う値も含まれてしまいますが、YAMLファイル名とフラグなので気にしなくてもいいでしょう。

…気になる場合は、YAMLファイルのハッシュキーにアンダースコアから始まるものが無いという前提で、次のようにするとか。

my $hash = {
    map { ( $_ => $self->config_param( $_ ) ) }
    grep { not /^_/ }
    keys %{ $self->config }
};

config_paramで値の追加・変更を行ったら、その都度YAMLファイルを書き換えてしまう

config_paramメソッドで値の追加・変更を行った場合はconfig_fileメソッドで指定したYAMLファイルを都度上書きしてしまいます。

$self->config_file( 'config.yaml' );
$self->config_param( new_key => 'new_value' );

# config.yaml に
#   new_key: new_value
# が追加されたものが書き込まれる

複数ファイルの読み込みをした場合はYAMLファイルの内容が大きく変わってしまうかも知れないので、config_paramメソッドで値を追加・変更しない方がいいですね。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/khashi/20100319/1268982513