Brethren, I have an application for which I find myself following Greenspun's Tenth Rule.

I need a way for users to provide expressions that will be evaluated at runtime. The primary reason for this is to be able to interpolate strings based upon conditions (a sort of templating application), but another use is to provide conditional routing logic for what questions to ask next (in a survey application).

I've been down this road before; it always starts out like this in the templating part:

# OK, users can write a variable name between {} brackets: while ($text =~ m/{([^\}]*}/g ) { #do some interpolation }
And, like this in the conditional routing part:
# hardcoded operation for routing: my ($if_question, $if_answer, $then_question, $else_question) = get_ha +rdcoded_logic(); if (get_answer($if_question) eq $if_answer) { set_next($then_question); } else { set_next($else_question); }

(Now, don't get me wrong. In general, YAGNI and KISS. And if the above works, and often it does, then OK.)

However, two things tend to happen if things mature and expectations increase. First is, you discover that you need the IF/THEN logic in the variable interpolation. (You might then decide, OK, I need a template engine here, and start using Template or Mason or whatever. Or, you might decide that you should combine your interpolation system with your routing system, to simplify syntax etc.)

Second is, you discover that the IF/THEN logic isn't enough; you need negation, and nesting IFs, and boolean operators, and grouping/precedence.

So, now you find yourself basically creating abstract syntax trees with control structures, grouping, operator definition, reserved words, ... holy crap, you've just fallen prey to Greenspun's Rule (or a corollary). And meanwhile, important business requirements are falling by the wayside as you create your own interpreter within Perl.

If this were a C program, I'd think "OK, I need to embed Lua." But this is Perl, after all: a scripting language itself, the exemplar of the string eval, the ultimate hackable environment. (And, all of the objects / methods / functions that I'd want to call or use are Perl native.)

Fellow monks, what do you suggest when your Perl app requires an embedded scripting language? (E.g., Lua, Safe.pm, ???) Ideally, the solution would be amenable to syntax-checking, and would either be so safe as to be able to accept mostly arbitrary user input to the script, or would be so parseable/structured that it becomes tractable to build an interface or abstraction layer for building expressions.


In reply to Avoiding Greenspun's Rule; scripting within Perl by rlucas

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.