princepawn has asked for the wisdom of the Perl Monks concerning the following question:
The Perl Core Language lacks builtin mechanisms for templating and programmatic block manipulation, both of which are necessary adjuncts to Perl's builtin support for higher-order functions.
Eval takes a string or a block. Of the two, only Perl strings can be added to or deleted from programmatically. Compare this with Lisp. In Lisp, eval takes a list and interprets it as a function call. The list can be added to or deleted from programmatically. Furthermore, the deletions can be made structurally, not in terms of strings. By structural, I mean that you can work at the level of program sentences not by mucking about with a bunch of hairy string manipulations. E.g., it is very easy to alter an evaluate-able block in Lisp, to say, get rid of the 3rd sentence in the eval-block, or to get rid of every sentence which makes a function to 'print. But with Perl, you have no hope of manipulating its evaluate-able and manipulable unit (the string) this way, without hairy and error-prone and full-of-exception string manipulation.
With that, I present a few lines of code that I wrote to do higher-order programming in Perl. The idea is that I am writing a program that connects to a series of FTP server, waits until something happens on any of the FTP servers and then does something else on the same FTP server.
Both something happens and something else are variant, but the cycling over hosts wasn't. So the high-level way to handle this is to make something happens and something else variables, in this case evaluatable Perl string. And submit them to a function which keeps trying until something happens and then does something else
my $until_no_upfile = "!ftp_file_exists ( '!!FTP_HOST!!', '$ftp::user', '$ftp::pass', +'$ftp::dir', '$script::upfile_name' );"; my $then_upload; map { $then_upload .= "ftp_upload ( '!!FTP_HOST!!', '$ftp::user', ' +$ftp::pass', '$ftp::dir', '$_' ); " } ($script::order_file, $script: +:upfile_name); host_cycle($until_no_upfile, $then_upload);
sub host_cycle { my ($_until,$_then)=@_; my $error_count; { for my $ftp_host (@ftp::host) { warn "ftp_host $ftp_host of @ftp::host"; my $until = $_until ; $until =~ s/!!FTP_HOST!!/$ftp_host/g; my $then = $_then ; $then =~ s/!!FTP_HOST!!/$ftp_host/g; warn "eval $until... ORIGINAL: **$_until**"; defined(my $retval = eval $until) || die "error: $@"; warn "retval $retval"; if (!$retval) { warn " * Unsuccessful"; next; } else { warn " * SUCCESSFUL"; warn "eval $then... ORIGINAL: **$_then**"; defined(my $retval = eval $then) || die "error: $@"; warn "retval $retval"; return 1; } } sleep $host_cycle::sleep; redo if (++$error_count < $host_cycle::retries); } }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Templating and Programmatic Block Manipulation in Perl
by merlyn (Sage) on Sep 28, 2000 at 17:41 UTC | |
by princepawn (Parson) on Sep 28, 2000 at 18:03 UTC | |
|
Re: Templating and Programmatic Block Manipulation in Perl
by mirod (Canon) on Sep 28, 2000 at 18:29 UTC | |
by Anonymous Monk on Sep 28, 2000 at 22:13 UTC |