Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

source filters in eval

by powerman (Friar)
on Feb 24, 2003 at 23:21 UTC ( [id://238288]=perlquestion: print w/replies, xml ) Need Help??

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

Is it possible to realize this in straight way?
Is it possible to redefine 'eval'?
Is it correct to use '::eval' instead of '&eval()'?
Any pitfalls?
#!/usr/bin/perl require 5.8.0; package filter; use Filter::Simple; FILTER { s/\bHi\b/Hello/g }; package main; BEGIN { $INC{'filter.pm'} = $0 } use Data::Dumper; sub eval ($) { open my $FH, '<', \$_[0]; local @INC = (sub {shift @INC; $FH}, @INC); do 'filtered eval.pl :-)'; }; $code = "use filter;\nprint 'Hi from eval!\n';die 'test'"; # filtered eval $ret = ::eval $code; print 'ret=',Dumper($ret),'err=',Dumper($@); # not filtered eval $ret = eval $code; print 'ret=',Dumper($ret),'err=',Dumper($@);

Replies are listed 'Best First'.
Re: source filters in eval
by djantzen (Priest) on Feb 25, 2003 at 01:08 UTC

    For the sake of clarity, I would name it something entirely different from CORE::eval. But using '::' to indicate the version found in the current package is preferable to '&' so that you avoid '@_' being passed unmodified from the calling context to the scope of the subroutine. In general, '&' should only preface subroutine calls in very specific and peculiar circumstances.

    That said, I'm wondering if you're planning to use this for some kind of code vetting, rather than the simple substitution in your example code? If so, then take a look at Safe and Opcode.

    Update: ihb is correct.


    "The dead do not recognize context" -- Kai, Lexx
      But using '::' to indicate the version found in the current package ...

      The :: doesn't indicate the subroutine is found in the current package. On the contrary. It clearly (?) specifies which package the subroutine is found in, and that's main.

      ... is preferable to '&' so that you avoid '@_' being passed unmodified from the calling context to the scope of the subroutine

      Using & doesn't necessarily mean @_ gets passed. That only happens if there is no parenthesis. If you look at the OP, you'll see that it asks about &eval(). And looking at the prototype of &eval makes it clear that it always is supposed to be called with one argument, so the behaviour you speak of is quite unlikely to happen.

      So, using :: is not preferable to &. The only advantage is that it still honours prototypes, but the downside is that you package qualify the subroutine so when you move it you'll have to rename all calls to it. The real fix, as you say, is to not name it "eval".

      ihb
      Hi,
      Maybe this is not clear indicated reasons of this trick (and re-inventing of eval).
      Problem is indicated in subject of node. E.g. source filters in 'eval' code magically don't work.
      So this is workaround of this problem and this post mean questions :
      - Is this is correct workaround ?
      - Can this be done more simply ?
      - And if it can't, how we can make this work magically ? E.g. if we can override (re-define) CORE::eval

        Isn't that because you used the expression (quoted) form of eval? The code would have already been compiled and (I think) source filters are applied at compile time. What happens if you try a block style eval?

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (2)
As of 2025-06-22 18:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.