Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

reval in Safe.pm 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 Safe.pm. 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
http://www.horus.com/~bjelli/         http://perlwelt.horus.at

Comment on reval in Safe.pm and objects
Select or Download Code
Re: reval in Safe.pm 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 Safe.pm 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

    --

    flounder

      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 Safe.pm 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 Safe.pm 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?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://195715]
Approved by VSarkiss
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (8)
As of 2014-09-19 10:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (135 votes), past polls