(perhaps an "Uncool Uses for Perl could turn into RFCs for Perl 7?)

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

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); } }

In reply to Templating and Programmatic Block Manipulation in Perl by princepawn

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.