Catalyst::Plugin::ConfigLoaderで環境毎に設定ファイルを用意する

基本の設定ファイルを用意しておいて、環境毎に異なる設定で上書きしたいことが良くあります。その際、ホスト名(uname -nで出るnodename)を使うと便利です。
CatalystなアプリケーションMyAppでMyApp->setupする前に

use POSIX;
__PACKAGE__->config->{file} = __PACKAGE__->config->{home} . '/conf/myapp.yml';
__PACKAGE__->config->{config_local_suffix} = lc [uname]->[1];

としておきます。

ホスト名mypcで実行した場合は

conf/myapp.yml
conf/myapp_mypc.yml

というファイルを、この順序で探して見つかったファイルを全て読み込んでくれます。この時、後から読み込んだファイルによって設定が上書きされます。(が、「どのように上書きされるのか」は詳しく調べていません。トップレベルの要素毎に上書きされているくさいですが)

ホスト名otherpcで実行した場合は

conf/myapp.yml
conf/myapp_otherpc.yml

というファイルが対象となります。ホスト毎にファイルを予め用意しておけば、動かす環境が変わると自動的に設定が変わるようになります。
myapp.ymlには「共通の設定」または「各環境で書き換えが失敗しても問題の起きない設定」だけを書いた方が良さそうです。コネクション情報などをmyapp.ymlに書いてしまうと、設定の書き換えに失敗したときにまずいことになりますので。

なお、fileプロパティに拡張子無しの値(またはディレクトリ名のみ)を渡すと、色々な拡張子をくっ付けて探してくれます。

use POSIX; 
__PACKAGE__->config->{file} = __PACKAGE__->config->{home} . '/conf';
__PACKAGE__->config->{config_local_suffix} = lc [uname]->[1];
設定方法が変わってました@Catalyst::Plugin::ConfigLoader-v0.17
use POSIX qw(uname);
my $nodename = lc [uname]->[1];
__PACKAGE__->config->{'Plugin::ConfigLoader'} = {
    file                => __PACKAGE__->config->{home} . '/conf',
    config_local_suffix => $nodename,
};
多分Catalyst側の変更だと思うのですが、Catalyst::setup_homeが実行されるタイミングが遅くなっていて、この時点で__PACKAGE__->config->{home}が使えないので、
use Catalyst::Utils ();
use POSIX qw(uname);

my $nodename = lc [uname]->[1];
__PACKAGE__->config->{'Plugin::ConfigLoader'} = {
    file                => Catalyst::Utils::home(__PACKAGE__) . '/conf',
    config_local_suffix => $nodename,
};
とすれば良いです。

としておくと、

conf/myapp.ini
conf/myapp.conf
conf/myapp.yml
...
conf/myapp_mypc.ini
conf/myapp_mypc.conf
conf/myapp_mypc.yml
...

という風に読み込んでくれます。