in reply to Hygienic eval of templates with perl code?

Eval::Closure is designed to help with eval'ing functions out of text.
  • Comment on Re: Hygienic eval of templates with perl code?

Replies are listed 'Best First'.
Re^2: Hygienic eval of templates with perl code?
by LanX (Saint) on Aug 27, 2014 at 12:36 UTC
    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.
        > choose a package name in such a way as to reduce the chance of a collision

        That's one of the standard techniques described in wikipedia, but it's not 100% cause it relies on convention.

        And I really prefer lexicals cause there scope is controllable, and I don't need to localize the variables in recursive calls.

        Furthermore a full qualified $Some::Really::Long::Package::foo++ can be so cumbersome that people would like using a placeholder again... maybe $<PCKG>::foo .

        A lexical variation of this package idea would be just one hash $<MyHash>{foo} and to only assure that this hash's name is unique.

        But I admit that in the future I might need to support "safe" package variables for this project too.

        Cheers Rolf

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