FreezeThaw で変数を保存
これぞチェックポイントリカバリ手法。
詳しい使い方はこちらに載ってました。
http://d.hatena.ne.jp/minesouta/20070924
へー。便利。
ただし、データに改行が含まれているとエラーが発生するみたい。
これのせいでどれだけ悩まされたことか。
ところで、変数の情報をそのまま保存するってことは
utf8 フラグのついた文字列とかも
decode せずにファイルに出力しても大丈夫なのかな?
とゆーことで確認。
use utf8; use strict; use warnings; use FreezeThaw qw( freeze thaw ); use Data::Dumper; use Devel::Peek; binmode(STDERR, ':encoding(euc-jp)'); { my $str = '日本語'; Dump $str; print "-----\n"; my $freeze = freeze $str; print STDERR Data::Dumper::Dumper($freeze); { open(my $fh, '>', 'freeze'); print $fh $freeze; close $fh } print "-----\n"; my @thaw; { open(my $fh, '<', 'freeze'); @thaw = thaw <$fh>; close $fh; } print STDERR Data::Dumper::Dumper(@thaw); print "-----\n"; print STDERR $thaw[0], "\n"; }
出力は
SV = PV(0x999b39c) at 0x9901348 REFCNT = 1 FLAGS = (PADBUSY,PADMY,POK,pPOK,UTF8) PV = 0x9a191e8 "\346\227\245\346\234\254\350\252\236"\0 [UTF8 "\x{65e5}\x{672c CUR = 9 LEN = 10 ----- $VAR1 = "FrT;\@1|\$3|\x{65e5}\x{672c}\x{8a9e}"; Wide character in print at test.pl line 22. ----- Extra elements in frozen structure: `本語' at test.pl line 32
どう考えてもアウトです。本当にありがとうございました。
ちなみに freeze の中身は
FrT;@1|$3|日本語
vimで見ると utf8 としてきちんと認識されていました。
あ、そいえばエラーも32行目(ファイルからの読込)で
出力に関してはエラーを出してないなー。
とゆーことは?ファイルから読み込む際に encode してあげればOK?
use utf8; use strict; use warnings; use FreezeThaw qw( freeze thaw ); use Data::Dumper; use Devel::Peek; binmode(STDERR, ':encoding(euc-jp)'); { my $str = '日本語'; Dump $str; print "-----\n"; my $freeze = freeze $str; print STDERR Data::Dumper::Dumper($freeze); { open(my $fh, '>', 'freeze'); print $fh $freeze; close $fh } print "-----\n"; my @thaw; { open(my $fh, '<', 'freeze'); binmode($fh, ':encoding(utf8)'); # ここでエンコードする @thaw = thaw <$fh>; close $fh; } print STDERR Data::Dumper::Dumper(@thaw); print "-----\n"; print STDERR $thaw[0], "\n"; }
出力は
SV = PV(0x81eb388) at 0x8151348 REFCNT = 1 FLAGS = (PADBUSY,PADMY,POK,pPOK,UTF8) PV = 0x8267c70 "\346\227\245\346\234\254\350\252\236"\0 [UTF8 "\x{65e5}\x{672c}\x{8a9e}"] CUR = 9 LEN = 10 ----- $VAR1 = "FrT;\@1|\$3|\x{65e5}\x{672c}\x{8a9e}"; Wide character in print at test.pl line 22. ----- $VAR1 = "\x{65e5}\x{672c}\x{8a9e}"; ----- 日本語
わ。できた。
とゆーことは、結局当たり前だけど、例えば euc-jp で保存したければ、保存する際に
binmode($fh, ':encoding(euc-jp)')
で euc-jp に decode して、読み込む際には
binmode($fh, ':encoding(utf8)')
をする必要があるってことですね。
結論。
utf8 フラグの文字列は encode すれば保存できるみたい。