なぜ、YAML::Syckを使用しているか?
perlでyaml形式のデータを扱うには、YAML, YAML::Syck, YAML::Tiny 等のモジュールがあります。
yamlファイルロード時のオーバヘッドの大きさは、
YAML > YAML::Syck > YAML::Tiny のようになるそうです。
http://search.cpan.org/~adamk/YAML-Tiny-1.32/lib/YAML/Tiny.pm
The original pure-Perl implementation YAML costs just over 4 megabytes of memory to load. Just like with Windows .ini files (3 meg to load) and CSS (3.5 meg to load) the situation is just asking for a YAML::Tiny module, an incomplete but correct and usable subset of the functionality, in as little code as possible.
しかし、YAML::Tiny には日本語処理に問題があるようなので、
現在、YAML::Syckを使用しています。
http://digit.que.ne.jp/visit/index.cgi?2006%C7%AF9%B7%EE#pYAML%3a%3aTiny%282%29
Load() Dump()
yamlストリーム<->perl構造体には、Load(), Dump()を使用します。
#!perl use strict; use warnings; use YAML::Syck; use Data::Dumper; my $yaml=<<EOF; common: name: てすとyaml stat_cols: - key: basic name: ベーシック - key: simple name: ヒーリング EOF my $pl = Load($yaml); print Dumper($pl); $yaml = Dump($pl); print Dumper($yaml); $pl = Load($yaml); print Dumper($pl);
bash-3.2$ ./foo.pl $VAR1 = { 'common' => { 'name' => 'てすとyaml' }, 'stat_cols' => [ { 'name' => 'ベーシック', 'key' => 'basic' }, { 'name' => 'ヒーリング', 'key' => 'simple' } ] }; $VAR1 = '--- common: name: "\\xE3\\x81\\xA6\\xE3\\x81\\x99\\xE3\\x81\\xA8yaml" stat_cols: - key: basic name: "\\xEF\\xBE\\x8D\\xEF\\xBE\\x9E\\xEF\\xBD\\xB0\\xEF\\xBD\\xBC\\xEF\\xBD\\xAF\\xEF\\xBD\\xB8" - key: simple name: "\\xEF\\xBE\\x8B\\xEF\\xBD\\xB0\\xEF\\xBE\\x98\\xEF\\xBE\\x9D\\xEF\\xBD\\xB8\\xEF\\xBE\\x9E" '; $VAR1 = { 'common' => { 'name' => 'てすとyaml' }, 'stat_cols' => [ { 'name' => 'ベーシック', 'key' => 'basic' }, { 'name' => 'ヒーリング', 'key' => 'simple' } ] };
Load() Dump()時の文字化解消する
先程の例のように日本語を含んだyamlデータを
Load()→Dump()→Load()すると元のyamlを取得できますが、
Load()→Dump()後に文字化けしていることが分かります。
このような文字化けを防ぐ?為、私の場合、予めunpack()でurl encodingしています。
(どこかのサイトから引用したものですが、それがどこだったか...)
sub ConvertEncoding_unpack { my($self,$p) = @_; my $r = ref($p); ### if [BLESSED] HASH REFERENCE ### if($r eq 'HASH' || ( !$r && $p =~ /=HASH\(.+\)/o )){ my $v; foreach $v (keys %{$p}){ $p->{$v} = $self->ConvertEncoding_unpack($p->{$v}); } } ### if [BLESSED] ARRAY REFERENCE ### elsif($r eq 'ARRAY' || ( !$r && $p =~ /=ARRAY\(.+\)/o )){ my $i=0; for ($i;$i <= $#{$p};$i++){ $p->[$i] = $self->ConvertEncoding_unpack($p->[$i]); } } ### if [BLESSED] CODE REFERENCE ### elsif($r eq 'CODE' || ( !$r && $p =~ /=CODE\(.+\)/o )){ } ### if SCALAR ### else{ $p =~ s/(\W)/'%' . unpack('H2', $1)/ego; } return $p; }