良い人ですか?いいえ。!!!!!



読解ポイント

パス変換関数


__path_to(hoge/hoge) HOME_ のように記入することにより、それぞれ Angelos::Utils->path_to('hoge/hoge') Angelos::Utils->HOME の結果を設定にぶち込むようになっている。またこの関数は、Data::Visitor::Callback によりすべての値をチェックするようになっている。

sub _config_substitutions {
    my $class    = shift;
    my $subs = {};
    $subs->{ HOME }    ||= sub { shift->HOME; };
    $subs->{ path_to } ||= sub { shift->path_to( @_ ); };
    my $subsre = join( '|', keys %$subs );

    for ( @_ ) {
        s{__($subsre)(?:\((.+?)\))?__}{ $subs->{ $1 }->( "Angelos::Utils", $2 ? split( /,/, $2 ) : () ) }eg;
    }
}

設定データの読み出し


条件文により、ここでは二つの違った対応をサポートしている。 1つ目は、ハッシュのリファレンスを渡すと、deep cloneをおこない設定データを作成している。2つ目は、それ以外(実はそれ以外というのは良くない、実際にはファイル名ならミタイな処理であるべき?)、ならYAMLファイルと決めうちで読み込むという仕様のようだ。

sub _make_config {
    my ( $class, $stuff ) = @_;
    if ( ref $stuff && ref $stuff eq 'HASH' ) {
        $config = Storable::dclone($stuff);
    }
    else {
        open my $fh, '<:utf8', $stuff
            or Angelos::Exception::FileNotFound->throw(
            message => "Can't open config: $!");
        $config = YAML::LoadFile($fh);
        close $fh;
    }
    $config;
}
課題
  • Hash refじゃなければファイル名というのはちょっと
  • YAML決めうちな点?
  • マルチバイトがなければ関係ないけど、マルチバイトがもしある場合utf flagはどうなるんだろ

ソース


package Angelos::Config::Loader;
use YAML ();
use Storable;
use Encode;
use Angelos::Config::Validator;
use Angelos::Exceptions;
use Data::Visitor::Callback;

sub load {
    my ( $class, $stuff, $schema ) = @_;
    my $config = $class->_make_config($stuff);
    Angelos::Config::Validator->validate_config( $config, $schema );
    $class->_substitute_config($config);

    return $config;
}

sub _substitute_config {
    my ($class, $config) = @_;

    # Data::Visitor::Callback uses Squirel.
    # Should we depends this module?
    my $v = Data::Visitor::Callback->new(
        plain_value => sub {
            return unless defined $_;
            $class->_config_substitutions( $_ );
        }
    );
    $v->visit( $config );
}


=head2 _config_substitutions( $value )

This method substitutes macros found with calls to a function. There are three
default macros:

=over 2

=item * C<__HOME__> - replaced with C<Angelos::Utils-E<gt>path_to('')>

=item * C<__path_to(foo/bar)__> - replaced with C<Angelos::Utils-E<gt>path_to('foo/bar')>

=back

=cut

sub _config_substitutions {
    my $class    = shift;
    my $subs = {};
    $subs->{ HOME }    ||= sub { shift->HOME; };
    $subs->{ path_to } ||= sub { shift->path_to( @_ ); };
    my $subsre = join( '|', keys %$subs );

    for ( @_ ) {
        s{__($subsre)(?:\((.+?)\))?__}{ $subs->{ $1 }->( "Angelos::Utils", $2 ? split( /,/, $2 ) : () ) }eg;
    }
}

sub _make_config {
    my ( $class, $stuff ) = @_;
    if ( ref $stuff && ref $stuff eq 'HASH' ) {
        $config = Storable::dclone($stuff);
    }
    else {
        open my $fh, '<:utf8', $stuff
            or Angelos::Exception::FileNotFound->throw(
            message => "Can't open config: $!");
        $config = YAML::LoadFile($fh);
        close $fh;
    }
    $config;
}

1;

SEE ALSO


タグ

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Wiki内検索

フリーエリア

hoge

Wiki内検索

フリーエリア

メンバーのみ編集できます