Why don't you use your currently favourite module, Parse::RecDescent? :) Seriously, you seem to be processing a grammar, to produce an interpreter. I'm no expert o nthat module, so I won't dig into this too deeply. I'm sure somebody else will. :]

As for critique on your current code, here are some incoherent thoughts. Most of all, I don't like your use of symbolic references. I can assume this isn't your actual code, that your syntax is actually described in an external datafile. Still, there's no need to keep the data in this way. I would use anonymous subroutines instead of the functions and method calls. Like:

$Commands{'log'}{'function'} = sub { createlog(shift) }; $Commands{'modules saveall'}{'function'} = sub { savemodules() }; $Commands{'modules loadall'}{'function'} = sub { loadmodules(shift) }; # extra example for module call: $Commands{'foo'}{'function'} = sub { Bar->foo(@_[0, 1]) };
You can generate these subs from strings using eval:
$code = 'print "Hello, $name!\n";'; $sub = eval "sub { my \$name = shift; $code }"; print "Ready to test:\n"; $sub->('world');
You get a compile time check of all code, this way — "compile time" meaning at the time your data structure gets filled.

You do have to be careful, if this code comes from an external source, to check that it doesn't contain malicipous code.

Also, use qr// for your patterns. Again, you get a compile time checks of all the patterns, plus it'll be faster at runtime.

I'm quite unhappy on how you actually do the parsing, but I'm not sure how I'd tackle that. I think I'd use (precompiled) regexes, not substr(). What if somebody typed "logic", would you try to do the "log" action? What if somebody typed "modules  saveall", would it fail to match? Still, if you don't want to use regexes, you definitely need to extract the words from the command line first, and then check if these words match.

And I think I would group the "modules saveall" and "modules loadall" under one common processing umbrella, "modules". For that, you'd have to have two subpatterns, one for each option.

As a summary... your data structure seems to have a bit of redundany, doesn't it? All you really need is the syntax/pattern on one hand, and the function on the other. The number of parameters is determined by the pattern.

Perhaps use Parse::RecDescent would still be the simpler solution... :)


In reply to Re: Complex dispatch table by bart
in thread Complex dispatch table by castaway

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.