in reply to interpolating preset strings in variable context (or something like that)

As Zaxo mentioned, you can use eval to do this, but it's not ideal. It can easily cause all sorts of hard to debug behavior, not to mention gaping security holes. I would rather approach it using a printf-like template. And instead of pulling the values from named variables directly, pull them from a hash. Here's an example:

my $template = "Hi %foo, I have a %bar.\n"; print fill($template, foo => 'mickey', bar => 'robot'); sub fill { my $template = shift; my %params = @_; $template =~ s/%([a-z]+)/$params{$1}/g; return $template; }

Update: I just noticed that the string you want to "fill in" looks like a function call. Maybe instead of a template type thing, you're actually looking to do a delayed call with different values? If that's the case, then you might be able to get away with a callback using closures.

my ($x, $y, $z); my $callback = sub { print $x, $y, $z, "\n" }; ($x, $y, $z) = (1, 2, 3); $callback->(); ($x, $y, $z) = (4, 5, 6); $callback->();

Update2: Another possiblity:

my $callback = sub { my ($x, $y, $z) = @_; print $x, $y, $z, "\n"; }; $callback->(1,2,3); $callback->(4,5,6);

I suppose, rather than randomly trying to guess exactly what you're doing, I should ask: What exactly are you doing? All you've given us to work with is the solution you've come up with, but we'd really be more help if you told us the actual problem you're trying to solve.

Replies are listed 'Best First'.
Re^2: interpolating preset strings in variable context (or something like that)
by mickey (Acolyte) on Mar 14, 2005 at 22:47 UTC

    Well, since you asked -- what I'm trying to do involves spidering a website to download various datasets that the website provides. The site uses several frames to allow the user to specify the desired dataset. One frame provides a cascading menu to choose the specific dataset; another frame provides a Javascript-generated set of form fields that specify the particular characteristics of the dataset chosen, and generates a code identifying the dataset; and the third form keeps a list of the dataset codes and ultimately provides the download functionality.

    I've tried doing this in several ways, but for the moment what I'm doing is looking at the source of all the variants of frame 2 for the Javascript arrays that generate the form fields and building a giant hash of all those arrays. Each of these pages generates a code that is more or less like Foo($a,$b,$c,$d), but each page has different variations, i.e. the variables are in different positions in the argument list, and there are sometimes other strings in the argument list as well.

    So I started off thinking that my giant hash would just have as another element for each of these alternate pages a string that represented the format of the code for that page -- hence my question. I've since discovered that each page might have a number of alternate code formats, so instead of a string I have a subroutine reference, that takes the variables I was trying to interpolate as arguments and returns the final code string.

    What I really want is a javascript parser that I could just get to run the javascript on the pages and tell me what the code is, and I tried to assemble one with JavaScript::SpiderMonkey, but I ended up trying to simulate a large subset of the DOM to get the JavaScript to work, which I couldn't figure out how to do and in any case didn't seem the most efficient way of doing this.

    That may or may not clarify what I'm attempting to do, but I think from the suggestions given here and what I've discovered about the problem that my original solution isn't the right one.

    Any suggestions as to how to do this without transferring the contents of the javascript hashes by hand into my perl hash, however, would be most heartily welcomed. Unfortunately it's a one-time task I have to do, so I only want to spend as long programming a solution as it would take me to do it by hand once, and so far that means I've given up trying to program it.

    Thanks to everyone for the advice on my original question.

      I would try to figure out what the JavaScript actually does before I'd try to write (or use) a general purpose JavaScript parser and interpreter. Most of the time, these type of JavaScript routines end up simply generating one URL or another, and the logic is easy enough to copy in Perl.