Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

reval in and objects

by bjelli (Pilgrim)
on Sep 06, 2002 at 17:30 UTC ( #195715=perlquestion: print w/replies, xml ) Need Help??
bjelli has asked for the wisdom of the Perl Monks concerning the following question:

dear brothers and sisters,

while using CGI::Session I learned about It's used in CGI::Session to savely eval stuff that has been written by Data::Dumper. This works great with normal data structures, but not with objects.

Say I have a Data::Dumper - string containing (among other stuff) an object:

$string = <<'EOM'; $data = { 'person' => bless( [ 42 ], 'Person' ) }; EOM

When I reval this string like so...

my $mysafe = Safe->new("MySafe"); $mysafe->reval($string);

...I get a proper object of class Person, but I can't call any of the methods:

Can't locate object method "method" via package "Person" (perhaps you forgot to load "Person"?)

Why is that? Is that a bug or a feature?

P.S. The full code is available

Brigitte    'I never met a chocolate I didnt like'    Jellinek

Replies are listed 'Best First'.
Re: reval in and objects
by flounder99 (Friar) on Sep 06, 2002 at 19:43 UTC
    From the Safe perldoc
    reval (STRING) This evaluates STRING as perl code inside the compartment. The code can only see the compartment's namespace (as returned by the root method). The compartment's root package appears to be the main:: package to the code inside the compartment.
    so the code in the compartment can't see any other namespaces so it doesn't know that the Person namespace exists. Try
    $string = <<'EOM'; use Person; $data = { 'person' => bless( [ 42 ], 'Person' ) }; EOM



      This will not properly work if the Person module uses operations not permitted inside the compartment, like (most probably) any IO.

      Makeshifts last the longest.

Re: reval in and objects
by Aristotle (Chancellor) on Sep 07, 2002 at 05:41 UTC
    Since, as others have pointed out, calling a method on a blessed reference stored inside a compartment will look for the appropriate package only inside the compartment, you will have to take your reference and manually rebless it.
    my $datacopy = $MySafe::data; bless $datacopy->{person}, 'Person';
    Now you can call Person's methods on $datacopy->{person}. You can actually rebless the reference with its own binding: bless $datacopy->{person}, ref $datacopy->{person};
    This will work, even though the package name referred to inside the compartment before, so long as $datacopy is inside an unrestricted package, not in MySafe. You could automate the process with a a loop like ref($_) and bless($_, ref $_) for values %$datacopy;
    Ultimately I'd return an anonymous hash from inside the configuration data:
    $string = <<'EOM'; { 'person' => bless( [ 42 ], 'Person' ) }; EOM my $data = Safe->new()->reval($string); ref($_) and bless($_, ref $_) for values %$data;

    Makeshifts last the longest.

Re: reval in and objects
by abell (Chaplain) on Sep 06, 2002 at 19:40 UTC
    First of all, thanks for having me take a look at Safe. A really enthralling read...
    Now, to your question:
    it seems the object created inside the Safe compartment $mysafe is blessed to a modified version of the module Person, possessing none of the methods of the original person.
    To let it have the "method" method, you should allow it into the compartment, with the instruction
    $mysafe->share( '&Person::method' );
    In short: it's a feature :-)

    Best regards

    Antonio Bellezza

    Update: It seems the reval'd object keeps some reference to the compartment it belonged to. So, even if the "method" method is invoked in the main context, it looks for it in the restricted environment and doesn't find the package altogether. I'll probably need to read more about perl internals before attempting to understand (not to mention explain) how this all works.
Re: reval in and objects
by bjelli (Pilgrim) on Sep 07, 2002 at 07:38 UTC
      Interesting. I didn't notice that reblessing a reference stored inside a compartment is sufficient as long as the bless is done from outside the compartment..

      Makeshifts last the longest.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://195715]
Approved by VSarkiss
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (6)
As of 2018-05-23 19:04 GMT
Find Nodes?
    Voting Booth?