Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

To use do or eval

by Angel (Friar)
on Jun 02, 2003 at 21:13 UTC ( [id://262493]=perlquestion: print w/replies, xml ) Need Help??

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

I am writing a small content management system and would like to allow some very select people to write scripts. Mainly myself and one other programmer.

I would like to have the section of script to exist in the a database along with the page and then when needed be pulled out and run. If there was an error I would not like it to break the entire script.

So which is the better choice eval() or do()? Eval seems to not have the error trapping capabilites that do does.

Replies are listed 'Best First'.
Re: To use do or eval
by perrin (Chancellor) on Jun 02, 2003 at 21:26 UTC
    You should use eval{}, in block form. There's not much need for do() these days. You will be able to trap errors with eval.

    To the larger point, putting code in the database is a common but terrible idea. You won't be able to edit with any of your normal tools, or track changes with CVS, or diff it, or grep it, etc. I know it sounds great before you've tried it, but it really ends up being a problem for most projects that do it.

      If the code is in a database, you cannot use the eval BLOCK form, but you must use the eval EXPR form. From the Camel book (p. 705):

      The first form traps run-time exceptions (errors) that would otherwise prove fatal, similar to the "try block" construct in C++ or Java. The second form compiles and executes little bits of code on the fly at run time, and also (conveniently) traps any exceptions just like the first form. But the second form runs much slower than the first form, since it must parse the string every time.

      For the do function there is no such thing as a do EXPR form; only do BLOCK and do FILE (and the deprecated do SUBROUTINE), so using your data-based scripts with do seems not feasible.

      CountZero

      "If you have four groups working on a compiler, you'll get a 4-pass compiler." - Conway's Law

        Good point. I was in a hurry to point out the problems with storing code in a database and forgot that this code would be in a variable.
      There's not much need for do() these days.

      But

      my $config = do "~/.proggyrc" or die "config error: " . ($@ || $!) . " +\n";
      will always hold a special place in my heart... :-)

      -sauoq
      "My two cents aren't worth a dime.";
      

        *sniff*

        I too am quite fond of do or die.

      You won't be able to edit with any of your normal tools, or track changes with CVS, or diff it, or grep it, etc. I know it sounds great before you've tried it, but it really ends up being a problem for most projects that do it.

      So provide a file based interface :)

      I had to work with code in a database once. It was great for performance (the filesystem on that box performed lousily), and writing check in/out scripts was only an hour or so work.

      Juerd # { site => 'juerd.nl', plp_site => 'plp.juerd.nl', do_not_use => 'spamtrap' }

        If you got better performance from an RDBMS than from a fileystem, something was set up wrong on that machine. Or it was running an OS with a lame filesystem.
        Exactly. Perlmonks would be in much better shape if the Everything codebase didn't have this problem. As it is, just getting the code to the site is a chore.
Re: To use do or eval
by broquaint (Abbot) on Jun 03, 2003 at 09:01 UTC
    I would say that string eval would be the way to go (not the least because do isn't orthorganal with eval :) e.g
    my $code = $dbh->selectrow_array($sql) or warn "no code - ", $dbh->errstr; do { eval($code); $@ } or warn "broken code - $@";
    So that will run the code from the database and warn if there are any errors when it's run.
    HTH

    _________
    broquaint

    update: as sauoq rightly points out below, my code was b0rken (I was under the impression eval returned the value of $@, how silly of me) it's now been fixed with a do block hack

      eval($code) or warn "broken code - $@";

      That's a big oops.

      The problem is that eval() returns whatever the eval'd code does. That would fail if the last expression in the code resulted in any false value, even if the code was perfectly fine. The Right Way™ is to check whether $@ is true.

      my $result = eval($code); warn "eval borked: $@" if $@;

      -sauoq
      "My two cents aren't worth a dime.";
      

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (6)
As of 2024-04-19 11:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found