Hi fwp,

once again, I'm thinking about some borderline fun with perl. "Borderline" because of the buzzword in the subject line that should repel all but the sickest and the .com types. (Now, which would I be?)

I've been wondering whether it is possible to implement some kind of mechanism that allows a Perl script to modify itself at runtime. Performance is not an issue as this isn't anything you'd want to use in production code. :)

So far, I see no way of achieving this. Using source filters, one may modify the source at compile-time and in fact I spent an hour doing so. (For a good reason, I never used source filters before, so it took me a bit to write that code.)

The result is Acme::Metification. Horrible name for a horrible hack.
http://search.cpan.org/author/SMUELLER/Acme-Metification-1.00/

Since the last upload, I have modified the module so you can define markers relative to which the positions of the "meta*" commands are interpreted. Additionally, I *should* be able to allow the functions to accept line numbers at run-time. (eg "meta marker $startline, $endline)

I would do that by inserting code for the meta command that determines $startline and $endline at runtime and evaluates the corresponding lines. (The code would have been originally generated in the lexical scope of the original array of code lines in the source filter.) Of course, in order to allow recursive "metaprogramming", one'd have to filter the code-to-be-evaluated first and apply the same transformations that were done to the rest of the source if necessary. (Which is a pain to implement but nevermind.)

I suppose I have successfully twisted most of your brains with that paragraph of bad english and bad ideas. ;)

What I am really interested in is a few better ideas on how one could go about implementing some concept of LISP-like metaprogramming for Perl. Any better ideas than the above?

Steffen
--
sub'_{q} tsuJ}}_();sub's{seek+DATA,0,0}sub'p{print&_}sub'r{reverse$_[0]}
@_=(('')x2,split" ",<DATA>);s!!&s,$_=<DATA>;s/}.*?}/$_[$s+1]/
if$s;s/(}.*?})/r$1/e;eval$_;p,$s++!efor@_[0..3];
__DATA__
} rehtona} } lreP} },rekcah}


Reply via email to