I wanted to build an awesome place for people to discuss module specific issues, but I don't have any more time for this, and there are much better places to discuss Perl-related issues. I'd recommend asking your question on Stack Overflow or on Perl Monks.
If you are looking for a Perl tutorial or Perl-related news, I hope these links will serve you well.
Posted on 2009-09-15 15:05:13-07 by jerome
Retrieving or thawing arbitrary OIO-based classes

I am trying to send OIO objects through IPC between processes on two different hosts. I have not been able to do so unless the receiving process has a proper 'use' statement for the package of the object being received. This prevents me from being able to send and receive "arbitrary" objects, i.e objects of a class not known at compile time by the receiving process. I have included a simple example below that does not rely on IPC but exhibits the same behavior (for what I believe are the same reasons).

Put in Foo.pm
package Foo;{ use strict; use warnings; use Object::InsideOut qw(Storable); my @bar :Field :Arg(Name=>'bar', Mandatory=>1); } 1;
Put in unload.pl
use strict; use warnings; use lib '.'; use Foo; my $file = 'object.stor'; my $object = Foo->new( bar => 10 ); $object->store($file);
Put in load.pl
use strict; use warnings; use Storable qw(retrieve); my $file = 'object.stor'; my $object = retrieve($file);

Run unload.pl and then load.pl. You should see this error: OIO::Args error: Unknown field name for class 'Foo': bar Package: Storable File: blib/lib/Storable.pm (autosplit into blib/lib/auto/Storable/_retrieve.al) Line: 331 Does this make sense? Is there any way to accomplish this? Jerome

Direct Responses: 11449 | Write a response
Posted on 2009-09-15 16:49:06-07 by jdhedden in response to 11448
Re: Retrieving or thawing arbitrary OIO-based classes
The 'data' for an OIO object is not stored in the object itself, but in lists/hashes within the object's class. Therefore the class must first exist in order for there to be a place to store the object data.

My suggestion is to do this in two steps:
1. First send over the class, and have the receiving end load that class using the following:
sub load_class { my $class = $_[0]; eval "require $class"; if ($@) { die("Failed to load $class: ".$@); } eval "$class->new()"; }
2. Then send over the object as you're doing now.

The last line in the subroutine is needed to ensure that $class is loaded and initialized properly. Hope this helps.
Direct Responses: 11451 | Write a response
Posted on 2009-09-15 18:01:40-07 by jerome in response to 11449
Re: Retrieving or thawing arbitrary OIO-based classes

Thanks for your prompt response. I actually tried something similar while troubleshooting but without the last call to 'new'. Your example assumes though that the receiving process knows how to instantiate $class. That won't be the case for me. Am I right to think that the sole purpose of your call to 'new' is to run 'initialize'? Before posting to this forum I realized that calling (a hacked-up version of) 'initialize' before thawing seems to do the trick as well. Would it make sense to allow users to do something like this instead?:

sub load_class { my $class = $_[0]; eval "require $class"; if ($@) { die("Failed to load $class: ".$@); } $class->initialize; }
Direct Responses: 11452 | Write a response
Posted on 2009-09-15 18:12:11-07 by jerome in response to 11451
Re: Retrieving or thawing arbitrary OIO-based classes
Oh that's why you wrapped the call to 'new' with an eval. Since the recipient won't know how to instantiate the class, the call to new is unlikely to succeed but it will only fail after calling 'initialize', right?. Let me try that in the real app. Thanks again.
Direct Responses: Write a response