Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Hygienic eval of templates with perl code?

by LanX (Saint)
on Aug 27, 2014 at 03:28 UTC ( [id://1098694]=perlquestion: print w/replies, xml ) Need Help??

LanX has asked for the wisdom of the Perl Monks concerning the following question:

Hi

I have the feeling of reinventing the wheel and would like to see other solutions...

I'm evaling code text which is composed of 2 snippets which are supposed to be correct in isolation.

Take as example using B::Deparse to back engineer a functions code and then wrapping new code around it before evaling. (something like this is shown in the Perl Hacks book)

Now this additional code could contain new symbols (identifiers) like variables, subnames or labels which might shadow equally named symbols in the original code.

This is known as Hygiene Problem.

I decided to solve this with a template system where new symbols need to be placeholders, which are renamed (extended with a suffix) if they conflict with old symbols.

Did anybody already try to solve this on CPAN?

I'd like to compare different approaches.

Cheers Rolf

(addicted to the Perl Programming Language and ☆☆☆☆ :)

  • Comment on Hygienic eval of templates with perl code?

Replies are listed 'Best First'.
Re: Hygienic eval of templates with perl code?
by Arunbear (Prior) on Aug 27, 2014 at 11:31 UTC
    Eval::Closure is designed to help with eval'ing functions out of text.
      Thanks, interesting module, I will learn a lot.¹

      (I think I subconsciously had this in mind =)

      But it doesn't seem to address the hygiene problem.

      As an illustration by extending the synopsis (untested)

      sub wrap { my ($old_body, $environment) = @_; my $new_body = <<'__WRAP__'; #---PRE_BODY my $foo++; # new var #<OLD_BODY># #--- POST_BODY print $foo; __WRAP__ $new_body =~ s/#<OLD_BODY>#/$old_body/g; my $code = eval_closure( source => "sub { $new_body }", environment => $environment, ); }

      Now the problem starts if $foo is part of the closure environment.

      I tried to solve this by using placeholders like $<FOO> in the wrapped code.

      This translates (regex) to $_FOO_ iff $_FOO_ is not already part of the environment.

      Otherwise it translates to something like $_FOO_A .

      (the suffix is incremented till there is no conflict)

      Other strategies (gensym, obfuscation, packages) are listed in the WP article, but I wanted to have a notation with readable symbols in the debugger.

      I hope it's clearer now.

      Cheers Rolf

      (addicted to the Perl Programming Language and ☆☆☆☆ :)

      ¹) especially how the use of PadWalker was avoided?

        Wouldn't a package give you readable symbols? e.g.
        $Some::Package::foo++; # new var
        instead of
        my $foo++; # new var
        You could also choose a package name in such a way as to reduce the chance of a collision.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1098694]
Approved by kevbot
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (4)
As of 2024-04-23 15:52 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found