我在Storable有冷冻物体的问题。当Storable解冻一个对象时,它应该加载该类。这通常是正确的,但有时却不是。这是一些示例代码......
#!/usr/bin/env perl -l
use strict;
use warnings;
use Storable;
if( fork ) {
}
else {
print "In child.";
# Load modules in a child process so the parent does not have them loaded
require Foo;
print $INC{"Foo.pm"};
print $Foo::VERSION;
Storable::store( Foo->new("http://example.com"), "/tmp/tb2.out" );
require DateTime;
print $INC{"DateTime.pm"};
Storable::store( DateTime->new(year => 2009), "/tmp/uri.out" );
exit;
}
wait;
print "Child is done.";
print "------------------------------";
print "DateTime is not loaded" if !$INC{"DateTime.pm"};
my $datetime = Storable::retrieve("/tmp/uri.out");
print $INC{"DateTime.pm"};
print $datetime->year;
print "Foo is not loaded" if !$INC{"Foo.pm"};
my $obj = Storable::retrieve("/tmp/tb2.out");
print $INC{"Foo.pm"};
print $obj->id;
非常简单的Foo.pm。
$ cat lib/Foo.pm
package Foo;
use strict;
use vars qw($VERSION);
$VERSION = "1.60";
sub new {
my $class = shift;
return bless { foo => 23 }, $class;
}
sub id { 42 }
1;
我从那个程序中得到......
In child.
lib/Foo.pm
1.60
/Users/schwern/perl5/perlbrew/perls/perl-5.16.2-threads/lib/site_perl/5.16.2/darwin-thread-multi-2level/DateTime.pm
Child is done.
------------------------------
DateTime is not loaded
/Users/schwern/perl5/perlbrew/perls/perl-5.16.2-threads/lib/site_perl/5.16.2/darwin-thread-multi-2level/DateTime.pm
2009
Foo is not loaded
Use of uninitialized value in print at /Users/schwern/tmp/test.plx line 38.
Can't locate object method "id" via package "Foo" at /Users/schwern/tmp/test.plx line 39.
正如您所看到的,它将很乐意加载DateTime而不是我的Foo模块。该对象已恢复,但未加载Foo.pm。我对Storable 2.34和perl 5.16.2有这个问题。
人们可以重复这个问题吗?有解决方案吗?
答案 0 :(得分:3)
DateTime定义STORABLE_freeze
和STORABLE_thaw
。人们可以推断出Storable会注意到这个类是否使用了一个钩子来冻结自己并寻找一个相应的钩子来解冻它。模块加载是钩子逻辑的一部分,不为Foo调用。
答案 1 :(得分:-1)
你总是可以做到
my $class = ref $obj;
eval "require $class";
不确定您在DateTime中看到的行为是否是DateTimes Storable-hooks的结果,但您不需要钩子来要求模块。