Perl には tie() というくみこみのサブルーティンがあって,ハッシュに設定した値を自動的に外部ファイルにかきこむことができる. ただし,このハッシュにはどんな値でもかきこめるというわけではなく,構造データをいれることができない. したがって,Perl の内部であつかう複雑なデータ構造をファイルにかきこむには,他のおおくの言語におけるのと同様に,データ構造を線形化 (serialize,シリアライズ) してやる必要がある. ここでは線形化 (serialization,シリアライゼーション) と逆線形化 (deserialization,デシリアライゼーション) の方法について書く.
私がこれまでよくつかってきた方法は,(k1 => v1, ..., kn => vn) というハッシュであれば 'k1=>v1|...|kn=>vn' というような文字列にする,(v1, ..., vn) という配列であれば 'v1|...|vn' というような文字列にするという方法である. 階層的になっていれば (ハッシュや配列がネストしていれば),階層ごとにことなるくぎり記号 (上記の例でいえば “|”) をつかえば split() でかんたんに要素をとりだすことができる. たとえば 2 階層の例をあげれば,(k1 => [v11, ..., vm], k2 => v2) というデータ構造を線形化するとき,くぎり記号として “|” と “,”をつかうことにすれば,'k1=>v11, ...,vm|k2=>v2' のように表現することができる. しかし,この方法では任意の階層をもつデータを線形化することができず,またデータの値としてつかえない文字が生じるため,汎用性がない.
Wikipedia の serialization という項目をみると,もっと汎用的な方法がのべられている. その一部を引用すると,つぎのとおりである.
use Storable; # Create a hash with some nested data structures my %struct = ( text => 'Hello, world!', list => [1, 2, 3] ); # Serialize the hash into a file store \%struct, 'serialized'; # Read the data back later my $newstruct = retrieve 'serialized';
この方法では線形化したデータをファイルにかいてしまうので,データベースに格納するのにはつかえない.
store
, freeze
のかわりに freeze
, thaw
をつかうと線形化した結果を内部データとしてうけとることができるということである.
(tie() のなかにこのしかけをくみこんでしまえば,構造化された値を直接データベースにかきこむことができて便利なのだが…)