YAML色々

コードリファレンスのシリアライズとデシリアライズ

use strict;
use warnings;

use YAML;
use Data::Dumper;

$Data::Dumper::Deparse = 1;
{
    no warnings ('once');
    $YAML::UseCode = 1;
}

my $obj = {
hello => sub {
       print "hello\n";
    },
    name => "hoge",
};

# serialize
my $yaml = YAML::Dump($obj);
warn $yaml;

# deserialize
my $obj2 = YAML::Load($yaml);
warn Dumper $obj2;

# call coderef
$obj2->{hello}->();

$YAML::UseCode = 1で$YAML::LoadCodeと$YAML::DumpCodeがtrueになる。
no warningsしないとused only onceのwarningsが出る。
結果は

---
hello: !!perl/code |
  {
      use warnings;
      use strict 'refs';
      print "hello\n";
  }
name: hoge
$VAR1 = {
          'hello' => sub {
                         use warnings;
                         use strict 'refs';
                         print "hello\n";
                     },
          'name' => 'hoge'
        };
hello

blessされたオブジェクトのシリアライズとデシリアライズ

{
    package Foo;
    
    use strict;
    use warnings;

    sub new {
        bless {name => 'hoge'},'Foo';
    }

    sub hello {
        print 'hello ' . shift->{name} . "\n";
    }
}

{
    package main;

    use strict;
    use warnings;
    
    use YAML;
    use Data::Dumper;

    $Data::Dumper::Deparse = 1;
    {
        no warnings ('once');
        $YAML::UseCode = 1;
    }
    
    my $obj = Foo->new;

    # serialize
    my $yaml = YAML::Dump($obj);
    warn $yaml;

    # deserialize
    my $obj2 = YAML::Load($yaml);
    warn Dumper $obj2;

    # call method
    $obj2->hello;
}

実行結果

$VR1 = bless( {
                     'name' => 'hoge'
               }, 'Foo' );
--- !!perl/hash:Foo
name: hoge
$VAR1 = bless( {
                     'name' => 'hoge'
               }, 'Foo' );
hello hoge

blessされたオブジェクトもシリアライズできるのはしらなんだ。