The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
Brad Appleton writes:
> sub explode($) {
>    local $_ = shift;
>    my @elems = map { /^\{([^\{\}]*)\}$/ ? [split ",", $1] : $_ }
>                   (split /(\{[^\{\}]*\})/ );
>    return @elems unless (@elems > 1);
>    my @alts = ("");
>    my ($e, $i);
>    for $e (@elems) {
>       (ref $e)  or  $_ .= $e for (@alts);
>       next unless (ref($e) eq 'ARRAY' and @$e);
>       my @cp = @alts;
>       for $i (0 .. $#{$e}) {
>          my @add = @cp;
>          $_ .= $e->[$i] for (@add);
>          splice @alts, ($i ? @alts : 0), ($i ? 0 : @alts), @add;
>       }
>    }
>    @alts;
> }

Well, as fun as that was. It was rather brutish and forceful. I thought
up a much better way (IMHO of course) on the way home from work today.

It seems I can make things much easier for myself if I precompute the
number of exploded items I'll be returning while I'm converting the given
string into an array of substring & sublist elements.

Then I just pre-allocate an empty string for each "alternative" to
return, and for each element, append it to the end of each alternative
(if the element is an m-item list, each item gets appended to only 
1/m-th of the set of alternatives).

  sub explode($) {
     my ($n, $e, @a) = (1, '');
     my @elems = map { !/^{(.+)}$/ ? $_ : (@a = split /,/,$1)
                                          && ($n*=@a) && [@a] }
                     split /({[^{}]+})/, shift;
     my @alts = map("", 1..$n);
     for $e (@elems) {
        $alts[$_] .= (ref $e) ? $e->[$_ % @$e] : $e  for (0 .. $#alts);
     }
     @alts;
  }

Thats about 7 statements instead of 15, and a bit more elegant IMHO.

Here's the newest source code!
-- 
Brad Appleton <bradapp@enteract.com> | http://www.enteract.com/~bradapp/
 "And miles to go before I sleep."   |  3700+ WWW links on CS & Sw-Eng

############################################################################

Date:         Thu, 25 Mar 1999 03:41:38 -0600 (CST)
From:         bradapp@enteract.com (Brad Appleton)
Subject:      Revised FastGlob::glob
To:           ppt@perl.com
Cc:           mengel@fnal.gov (Marc Mengel)
Reply-to:     bradapp@enteract.com
Delivery-Date: Thu Mar 25 02:48:18 1999
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit

I've made some fairly significant changes (enough so that I think it
takes up less space to resend the entire file instead of a patch-diff).

I did the following:
   * Revamped the PODs to document 'glob' both as a script/command,
     and as a function (with emphasis on the command-interface).

   * Added a subsections to the POD documentation for the DESCRIPTION
     describing the glob-syntax that is accepted, and also added the
     OPTIONS, RETURNS and DIAGNOSTICS sections to the PODs

   * Changed the name of some of the subroutines to have a _glob suffix,
     (match_glob, explode_glob, escape_glob, unescape_glob)

   * Fixed a god-awful bug in explode_glob that made it expand things
     not only in the wrong order, but with the wrong set of permutations.

   * Error messages and standard output should now be much more closely
     in line with what is produced by csh.

   * Modified explode_glob to handle nested {...} word-sets, and to
     escape [{}\\] with backslash, and leave '{}' untouched.

     The result is a horridly ugly regexp-search-and-replace and too
     many (i.e.  inefficient) repeated "escaping" of special characters
     due to recursion. Someone with more energy and patience than I is
     more than welcome to remedy this; I'm all tapped out at present.

Latest version of FastGlob.pm (v1.2_05) follows my signature.
-- 
Brad Appleton <bradapp@enteract.com> | http://www.enteract.com/~bradapp/
 "And miles to go before I sleep."   |  3700+ WWW links on CS & Sw-Eng

#########################################################################