in reply to Re: How to use Safe to compile anonymous subs
in thread How to use Safe to compile anonymous subs

Thanks, but using the suggested pattern, I don't understand how to pass arguments to the inner code:
my $code = 'my $a = shift; warn $a'; my $compartment = Safe->new(':default'); $safe = sub { $compartment->reval($code) || die $@ }; $safe->(42);
Is there any way to do this?

Replies are listed 'Best First'.
Re^3: How to use Safe to compile anonymous subs
by moritz (Cardinal) on Jul 30, 2008 at 19:50 UTC
    You can by sharing variables. Somehow I didn't manage to do with simply sharing a variable and localizing it, but I'm quite sure it can be done.

    This is my workaround for now:

    #!/usr/bin/perl use Safe; use IO::File; our @args; my $code =<<'END'; my @args = pass_options(); return "Arguments: @args\n"; END my $compartment = Safe->new; sub pass_options { @args }; $compartment->share('&pass_options'); $safe = sub { local @args = @_; $compartment->reval($code) || die $@}; print $safe->(1, 2, 3); __END__ Arguments: 123

    This takes the sideway of sharing a sub that returns the arguments. Not ideal, but at least it works.

Re^3: How to use Safe to compile anonymous subs
by Perlbotics (Archbishop) on Jul 30, 2008 at 20:04 UTC
    This seems to work. The localised copy is shared into the compartments namespace.
    #!/usr/bin/perl use Safe; use IO::File; my $compartment = Safe->new; my $safe = sub { local @SHAREDARGS = @_; $compartment->share('@SHAREDARGS'); my $code = 'print "Got: ", join (", ", @SHAREDARGS),"\n" +'; $compartment->reval($code) || die "die $@" }; print $safe->(42, 47, 11 , "xyz"); __END__ Got: 42, 47, 11, xyz
Re^3: How to use Safe to compile anonymous subs
by rir (Vicar) on Jul 30, 2008 at 20:02 UTC
    What you want is probably:

    my $code = 'sub { my $arg = shift; warn $arg; }';

    Update: Since the above looks alot like your original post, here is more.

    I've never used Safe but my doc's indicate that you need a namespace as the first arg to Safe->new.

    use Safe; my $code = 'sub { my $arg = shift; warn $arg; }'; my $safe = Safe->new(); my $ssub = $safe->reval( $code) || die ; $ssub->( "hello$/" ); &$ssub( "hello$/" );

    Be well,
    rir