[LA.pm] Thanks for letting me present

Ben Tilly btilly at gmail.com
Thu Jun 21 13:06:04 PDT 2012


On Thu, Jun 21, 2012 at 11:37 AM, David Oswald <daoswald at gmail.com> wrote:
> On Thu, Jun 21, 2012 at 2:05 AM, Ben Tilly <btilly at gmail.com> wrote:
>> Hrm, I guess I gave all of the architecture, but didn't show what the
>> answer to Eric's problem could look like.  Let me do that.
>>
>
> <snip>
>
>>    insert_foreach => sub {
>>      my ($expander, $hashref, $var, $range, $key, $value) = @_;
>>      for (@$range) {
>>        my $expanded = $expander->expand({
>>          $var => $_,
>>          key => $key,
>>          value => $value,
>>        });
>>        $hashref->{$expanded->{$key}} = $expanded->{$value};
>>      }
>>      return undef; # We do not use this again.
>>    },
>
> <snip>
>
> Interesting approach... I see how it works, but someone with such a
> need might not immediately think of it.  Perhaps you could provide a
> "cookbook" POD document with your module.
> Just a thought for version 0.02. :)

Heh, you think I'm adding this in version 0.02??

I thought more about it.  If I went down this road, I'd be inclined to
make it more lisp-like, and have some useful functionality available
by default so that people don't need to write those messy bits.  That
would reduce Eric's solution to something like this:

  {
    subdomain_count => 5,
    subdomain_template => {
      domain => '`m[% i %].campusexplorer.com',
      foo => 'bar',
    },
    dummy =>
      '[% foreach i [% range 1 [% subdomain_count %] %]
            [% insert m[% i %] [% subdomain_template %] %]',
  }

Which would expand to:

  {
    subdomain_count => 5,
    subdomain_template => {
      domain => 'm[% i %].campusexplorer.com',
      foo => 'bar',
    },
    m1 => {
      domain => 'm1.campusexplorer.com',
      foo => 'bar',
    },
    m2 => {
      domain => 'm2.campusexplorer.com',
      foo => 'bar',
    },
    m3 => {
      domain => 'm3.campusexplorer.com',
      foo => 'bar',
    },
    m4 => {
      domain => 'm4.campusexplorer.com',
      foo => 'bar',
    },
    m5 => {
      domain => 'm5.campusexplorer.com',
      foo => 'bar',
    },
  }

Add configurability for the delimiters, add a convenient set of
built-ins, and you really would have a recognizable (though small)
Lisp.

But I'm not sure whether anyone but me would find this approach comfortable.

> By the way, from perldoc perlre:
>
> "The \A and \Z are just like "^" and "$", except that they won't match
> multiple times when the /m modifier is used, while "^" and "$" will
> match at every internal line boundary. To match the actual end of the
> string and not ignore an optional trailing newline, use \z ."
>
> So your ^ .... \z is obviously OK since it should be impossible to
> match multiple times at the beginning of a line (^) if you're
> anchoring to the end of the string with \z... and of course you're not
> even using the /m modifier, so the discussion is just theoretical.  I
> suppose someone could write something like this:  /(?:^[^\n]+\n)+\z/
> and end up matching multiple lines despite the \z anchor, but it seems
> not that useful.

Ah right.  Now I vaguely remember having looked at \A and \Z and
having concluded that I almost never would want to use them, and
therefore shouldn't try to memorize them.

> _____ ...... ----- A tangent we visited last night: Version numbers
> ----- ...... _____
>
> I was thinking more about the version numbering question.  ...again
> this is theoretical because nobody is actually suggesting that one
> SHOULD use a version 0.00, but the question of whether one COULD came
> up.  I think there are risks.  Of course the string '0.00' evaluates
> to true under the "zero but true" rule.  But code that treats a
> version number numerically would get a numeric evaluation of the
> string.  Subsequent Boolean tests would get 'false'.
>
> our $VERSION = '0.00';
>
> # Boolean test is based on the string value: True.
> if( $VERSION && $VERSION =~ /^[0.]+$/ ) {
>    warn "Zero but true.";
>
> # Numeric relational comparison: From this point forward
> # Boolean tests will be based on numeric value: False.
> if( $VERSION < 0.02 ) {
>    warn "We prefer a more stable version!";
>
> # Naive test...
> if( ! $VERSION ) {
>    warn "Zero and false.";
> }
>
> This is a contrived example, but without diving into the internals of
> ExtUtils::MakeMaker, Module::Build, and all the other entities that
> look at version numbers, it's impossible to be certain that a zero for
> a version number wouldn't break something.  ...and it probably would
> only break something on a production machine six months from now when
> someone upgrades a seemingly unrelated module.
>
> Actually perldoc perlmodlib does provide a suggestion that if
> implemented would break a zero-based version number.  Developer's
> release version numbers.
>
> our $VERSION = '0.00_00';
> $VERSION = eval $VERSION;
>
> From perlmodstyle: "With that trick MakeMaker will only read the first
> line and thus read the underscore [treating this as a developer's
> release], while the perl interpreter will evaluate the $VERSION and
> convert the string into a number. Later operations that treat $VERSION
> as a number will then be able to do so without provoking a warning
> about $VERSION not being a number."
>
> That's fine for version numbers that evaluate to Boolean true, but
> somewhere, someday there will be some module that interacts with ours
> and does a Boolean test of the version number.  It's bound to cause an
> element of surprise somewhere.
>
> I don't think anyone looks to me as an authority on PAUSE, EU::MM, and
> so on... but I'll go ahead and suggest it anyway: Although one
> probably COULD, one definitely SHOULD NOT use any form of zero or zero
> string as a version number.  Behavior is too unpredictable.

I'm glad that your more in depth analysis agreed with our gut reaction
last night.


More information about the Losangeles-pm mailing list