ディレクトリツリーを使った設定ファイル管理・その 3 #
設定ファイルとかだと場所は固定だろうから、アドホックに、しかし多少は頭を使って、というのでちょっとだけお遊び。お遊びなのでそのままでは使えません。
package Customer::Info;
use strict;
use warnings;
use Carp;
use File::Finder;
#http://blog.livedoor.jp/dankogai/archives/50076993.html
sub AUTOLOAD {
my $this = shift;
my $name = our $AUTOLOAD;
$name =~ s/.*:://o;
$name eq 'DESTROY' and return;
ref($this) && $name or croak "Undefined subroutine $name called";
{
no strict 'refs';
*$name = sub {
# warn "$name predefined";
my $self = shift;
@_ and $self->{$name} = shift;
ref $self->{$name} eq 'HASH' and bless $self->{$name}, ref($self);
$self->{$name};
};
}
# warn "$name first called";
@_ and $this->{$name} = shift;
ref $this->{$name} eq 'HASH' and bless $this->{$name}, ref($this);
$this->{$name};
}
sub new {
my $class = shift;
my $target_dir = shift or croak "not defined target";
my $self = bless { config_info_target_dir => $target_dir,}, $class;
$self->_load();
return $self;
}
sub _load {
my $self = shift;
for my $file ( File::Finder->type('f')->in($self->{config_info_target_dir}) ) {
my @tmps = File::Spec->splitdir($file);
$self->{$tmps[-2]}->{$tmps[-1]} = '1';
}
return $self;
}]
使い方
$config = Customer::Info->new('/path/to/config');
print Dumper $config;
実行結果
$VAR1 = bless( {
'app00' => {
'id.txt' => '1',
'license.txt' => '1'
},
'app01' => {
'id.txt' => '1',
'license.txt' => '1'
},
'config_info_target_dir' => '/path/to/config'
}, 'Customer::Info' );
- hash に /path/to/config が含まれないように
- $config->{app00} ではなくて $config->app00 で使えるように
- app00 以下にはディレクトリは存在せず、ファイルだけということにしてしまった
まぁ、hash をシンプルにするだけなら $hoge = $config->{path}->{to}->{config} とかでいいし、license.txt とかあるから結局 {’license.txt’} って書かないといけないし、階層構造決め打ちしてしまってるし、深く考えずテケトウに作ったのでまともに使えないと思うし、じゃぁ何で書いてるのかというと、
- AUTOLOAD のところがカッコイイと思ったのでメモ
- File::Spec は今後もっと使っていきたい気もするのでメモ
- 配列に負の数でアクセスするのって、他の人を混乱させそうなので使わない方がいいよな、って思ってメモ
ということで、未来の自分宛の手紙。