
「全裸は違法だということを言われた。ええええ、そんな法律があるのか?Debugはできるようになるかもしれない。」と思っておセンチなyappoです。
hashを簡単にmergeするCPAN moduleとしてHash::Mergeがあるのは有名ですが、デフォルトだと色々頑張ってマージしちゃうので、例えばHTTP::Engine::Middlewareの使いたいMiddlewareをARRAY refで書いちゃったりして、base.yamlとproduction.yamlでmergeした時に、以下のような混ざりかたでとんでも無い目にあいます。
use strict;
use warnings;
use YAML;
use Hash::Merge;
my $base = {
Middlewares => [
{ module => 'HTTPSession', config => { name => '開発やらステージング用の設定だよ' } },
{ module => 'MethodOverride' }, # 全部で共通して使いたいよ
],
name => 'base',
base => 1,
};
my $production = {
Middlewares => [
{ module => 'HTTPSession', config => { name => '本番用の設定だよ' } },
],
name => 'production',
production => 1,
};
my $config = Hash::Merge::merge($base, $production);
print Dump($config);
---
Middlewares:
- config:
name: 開発やらステージング用の設定だよ
module: HTTPSession
- module: MethodOverride
- config:
name: 本番用の設定だよ
module: HTTPSession
base: 1
name: base
production: 1
これは、マズいですね、HTTPSessionの設定を開発と本番で別けたいのにARRAYだから全部混ざっちゃいます。
そんな時はspecify_behaviorでmergeのルールを弄れるのです。左のreftype => 右のreftypeみたいな形で、左の要素がSCALARで右の要素がARRAYだったどうこうするみたいな事が出来ます。
ぶっちゃけ左の要素がHASHで右の要素がARRAYとかだいぶあり得ないので、そういった組み合わせになったらdieするとかすると混乱無いと思います。
こんかいは左右でreftypeが違うと混乱するし、ARRAY同士でmergeしないで右要素だけを生かしたいと言う要望でbehaviorを作ったです。あと、behavior作っちゃうとデフォルトの振る舞いが上書きされるのでget_behaviorで今の振る舞いを取っておいて用が済んだらset_behaviorすると良いと思います。
use strict;
use warnings;
use YAML;
use Carp;
use Hash::Merge;
my $base = {
Middlewares => [
{ module => 'HTTPSession', config => { name => '開発やらステージング用の設定だよ' } },
{ module => 'MethodOverride' }, # 全部で共通して使いたいよ
],
name => 'base',
base => 1,
};
my $production = {
Middlewares => [
{ module => 'HTTPSession', config => { name => '本番用の設定だよ' } },
{ module => 'MethodOverride' }, # array は上書きされるので、こっちにもかく
],
name => 'production',
production => 1,
};
my $old_behavior = Hash::Merge::get_behavior;
Hash::Merge::specify_behavior({
SCALAR => {
SCALAR => sub { $_[1] },
ARRAY => sub { Carp::croak 'SCALAR and ARRAY cannot merge in config file.' },
HASH => sub { Carp::croak 'SCALAR and HASH cannot merge in config file.' },
},
ARRAY => {
SCALAR => sub { Carp::croak 'ARRAY and SCALAR cannot merge in config file.' },
ARRAY => sub { $_[1] },
HASH => sub { Carp::croak 'ARRAY and HASH cannot merge in config file.' },
},
HASH => {
SCALAR => sub { Carp::croak 'HASH and SCALAR cannot merge in config file.' },
ARRAY => sub { Carp::croak 'HASH and ARRAY cannot merge in config file.' },
HASH => sub { Hash::Merge::_merge_hashes( $_[0], $_[1] ) },
},
}, 'MY_CONFIG_STRICT_MODE' );
my $config = Hash::Merge::merge($base, $production);
Hash::Merge::set_behavior( $old_behavior );
print Dump($config);
---
Middlewares:
- config:
name: 本番用の設定だよ
module: HTTPSession
- module: MethodOverride
base: 1
name: production
production: 1
素敵にマージされましたね。
Posted by Yappo at 2009年05月28日 15:26
| TrackBack
| Perl
rs gold | RS money | buy rs money | buy rs gold | cheap rs gold | cheap rs money | Runescape gold | Runescape money | Runescape power leveling | Runescape powerleveling | rs power leveling | rs powerleveling | rs accounts | rs account | runescape accounts | runescape account | rs powerleveling | Runescape powerleveling | rs power leveling | Runescape power leveling | Runescape gold|Runescape Money | Runescape gold|Runescape Money | rs gold|rs Moneyrs gold | RS money | buy rs money | buy rs gold | cheap rs gold | cheap rs money | Runescape gold | Runescape money | Runescape power leveling | Runescape powerleveling | rs power leveling | rs powerleveling | rs accounts | rs account | runescape accounts | runescape account | rs powerleveling | Runescape powerleveling | rs power leveling | Runescape power leveling | Runescape gold|Runescape Money | Runescape gold|Runescape Money | rs gold|rs Moneyrs gold | RS money | buy rs money | buy rs gold | cheap rs gold | cheap rs money | Runescape gold | Runescape money | Runescape power leveling | Runescape powerleveling | rs power leveling | rs powerleveling | rs accounts | rs account | runescape accounts | runescape account | rs powerleveling | Runescape powerleveling | rs power leveling | Runescape power leveling | Runescape gold|Runescape Money | Runescape gold|Runescape Money | rs gold|rs Moneyrs gold | RS money | buy rs money | buy rs gold | cheap rs gold | cheap rs money | Runescape gold | Runescape money | Runescape power leveling | Runescape powerleveling | rs power leveling | rs powerleveling | rs accounts | rs account | runescape accounts | runescape account | rs powerleveling | Runescape powerleveling | rs power leveling | Runescape power leveling | Runescape gold|Runescape Money | Runescape gold|Runescape Money | rs gold|rs Moneyrs gold | RS money | buy rs money | buy rs gold | cheap rs gold | cheap rs money | Runescape gold | Runescape money | Runescape power leveling | Runescape powerleveling | rs power leveling | rs powerleveling | rs accounts | rs account | runescape accounts | runescape account | rs powerleveling | Runescape powerleveling | rs power leveling | Runescape power leveling | Runescape gold|Runescape Money | Runescape gold|Runescape Money | rs gold|rs Money
Posted by: Runescpae power leveling at 2009年06月23日 15:47