Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Can you check the syntax of a eval() before executing it?

by slloyd (Hermit)
on May 06, 2002 at 20:13 UTC ( #164431=perlquestion: print w/ replies, xml ) Need Help??
slloyd has asked for the wisdom of the Perl Monks concerning the following question:

is there anyway to check the code passed to an eval() for syntax before executing it?

Comment on Can you check the syntax of a eval() before executing it?
Re: Can you check the syntax of a eval() before executing it?
by erikharrison (Deacon) on May 06, 2002 at 20:20 UTC

    There isn't a really good way to do this within Perl . . . however, if you absolutely must double check, you can execute perl from within your program on a temp file containing the source, using the -c switch. But you don't want to do that.

    Cheers,
    Erik

    Update: Chmrr makes a good point about BEGIN blocks . . . see below

      This has been discussed previously here at the monastery, but I can't seem to find where. The general consensus is that it is not possible. The perl -c trick will not prevent code from being executed; see the following, for example:

      [chmrr@supox chmrr]$ perl -c BEGIN {print "Nope!"} Nope!- syntax OK

      perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER'

Re: Can you check the syntax of a eval() before executing it?
by belg4mit (Prior) on May 06, 2002 at 20:27 UTC
    As prevously mentioned, not really. In fact that's kind of one of the uses of eval now isn;t it? You might consider evaling it in another package though, say via Safe. This could prevent it from having any actual impact while letting you get a syntax check. In fact, this coul allow you to be more restrictive in what you consider valid.

    --
    perl -pew "s/\b;([mnst])/'$1/g"

Re: Can you check the syntax of a eval() before executing it?
by Matts (Deacon) on May 06, 2002 at 22:18 UTC
    The generally accepted way to do this is to prefix the eval code with "return;", so you'd do:
    eval "return;" . $code;
    However it won't prevent the execution of BEGIN blocks, and when you want to execute it, you have to compile it again.
      Another, possibly sillier way would be to eval it into an anonymous subroutine:
      my $coderef = eval "sub{$code}" or die "Error in code: $@"; $coderef->(); # execute the code
      That way one wouldn't have to recompile the code, if you really need that kind of optimization. It is also quite possible that there is code that can't be evaled into a sub like this. But maybe it'll suffice. :)
      You have moved into a dark place.
      It is pitch black. You are likely to be eaten by a grue.

        ... and it still executes those pesky BEGIN blocks.

        Some days you just have to love Perl's DWIDM features.

      Well, if we want to be really careful about checking what $code is going to do, why not do some more analysis of its content:
      my $codeBegin = ""; if ( $code =~ /BEGIN\s*\{/ ) { # tricky part here: try to locate the matching close brace # (this would require parsing character-by-character, to # handle various quote operators and escapes -- a worthwhile # project for a module developer, not something I can do here). # check that part separately, assign it to $codeBegin and # delete it from $code; } # now check whatever's left in $code, and if everything's # okay, then: eval "$codeBegin $code";
      But would we also have to check separately for an END{} block?

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (6)
As of 2014-09-19 03:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

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











    Results (129 votes), past polls