[ABE.pm] My first enclosure doesn't work. :-(

Ricardo SIGNES rjbs-perl-abe at lists.manxome.org
Sat Oct 27 05:53:21 PDT 2007


* "Faber J. Fedor" <faber at linuxnj.com> [2007-10-26T19:45:06]
> > Well, for one thing, you're even considering using string eval. :)
> 
> But you guys use it all the time!

!?!?

Who are you talking about?!  I use string eval for exactly one use case,
excepting REALLY weird exceptions:

  eval "require $module; 1";

In fact, I wrote a module that scans code to make sure it doesn't contain any
string eval uses other than that.

Do not confuse these two things:

  eval "if ($var) { do_something }";

  eval { if ($var) { do_something } };

They are WILDLY different.

The first one accepts a string and tries to use it like Perl code.

The second one runs the included code, which was compiled along with everything
else, and just catches exceptions.

The first one is for use in case of REALLY REALLY weird needs.  The second is
for use ALL THE TIME.

> > This code does *not* dynamically generate an if/else tree.  Basically, in
> > dynamic Perl, you Just Don't Do That.  if/else trees are literal structures,
> > and you'd have to generate code and then eval it.  
> 
> That's what I was trying to do. I wanted a function to write a function
> as mentioned in the first paragraph on Chapter 7 of HOP.

As far as I know, string eval is not used for any of the techniques in HOP.

> > This is a red flag the size of Texas.  
> 
> Can you explain the concept of "code writing code" or "programs writing
> programs" then cuz I'm WAY off base. 

You could use the phrase "code writing code" to mean "code that builds a string
and then turns it into a sub," I suppose, but it's not what's really meant.

It's about further and further refining what you need to write by building
tools that convert your input data into code.  Example:

  sub make_notifier {
    my ($frequency, $from, $to) = @_;

    my $last_sent = 0;

    sub {
      return unless time - $last_sent > $frequency;

      send_email(
        build_an_email,
        $to,
        $from,
      );

      $last_sent = $frequency;
    };
  }

...then elsewhere...

  my $notifier = make_notifier(3600, 'root at example.com', 'faber at example.com');

Now you have code ($notifier) written by code ($make_notifier) that sends a
message to X from Y only if it has been at least Z seconds since the last time
it did this.

Maybe your program that uses this always uses similar settings, so you write:

  sub make_std_notifier { make_nofifier(3600, 'root at example.com', shift) }

So make_std_notifier also builds code, but with a smaller range of
customizaiton.

  my @notifiers = map { make_std_notifier($_) } @admins;

A more complex, but possibly understandable example can be find in these
modules:

  http://search.cpan.org/src/RJBS/String-Truncate-0.102/lib/String/Truncate.pm

  http://search.cpan.org/src/RJBS/Number-Nary-0.102/lib/Number/Nary.pm

-- 
rjbs


More information about the ABE-pm mailing list