NAME
    Text::Glob::Expand - permute and expand glob-like text patterns

VERSION
    This document describes Text::Glob::Expand version 0.1

SYNOPSIS
    The original use case was to specify hostname aliases and expansions
    thereof. For example, it supports basic expansion of the glob expression
    into its permutations like this:

        use Text::Glob::Expand;

        my $hosts = "{www{1,2,3},mail{1,2},ftp{1,2}}";
        my $glob = Text::Glob::Expand->parse($hosts);

        my $permutations = $glob->explode;
        # result is: [qw(www1 www2 www3 mail1 mail2 ftp1 ftp2)]

    But additionally, to generate full hostnames, it supports a method to
    expand these permutations using a format string:

        my $permutations = $glob->explode_format("%0.somewhere.co.uk");

        # result is:
        # {
        #     www1 => 'www1.somewhere.co.uk',
        #     www2 => 'www2.somewhere.co.uk',
        #     www3 => 'www3.somewhere.co.uk',
        #     mail1 => 'mail1.somewhere.co.uk',
        #     mail2 => 'mail2.somewhere.co.uk',
        #     ftp1 => 'ftp1.somewhere.co.uk',
        #     ftp2 => 'ftp2.somewhere.co.uk',
        # }

INTERFACE
  "$obj = $class->parse($string)"
    This is the constructor. It implements a simple state-machine to parse
    the expression in $string, and returns a "Text::Glob::Expand" object.

    You don't really need to understand the structure of this object, just
    invoke methods on it. However, see "PARSING RULES" for more details of
    the expression and the internal structure of the object returned.

  "$arrayref = $obj->explode"
    This returns an arrayref containing all the expanded permutations
    generated from the string parsed by the constructor.

    (The result is cached, and returned again if this is called more than
    once. See $MAX_CACHING.)

  "$hashref = $obj->explode_format($format)"
    This returns a hashref mapping each expanded permutation to a string
    generated from the $format parameter.

    (The return value is not cached, since the result depends on $format.)

PARSING RULES
    Using a notation based on a subset of the Backus Naur Form described by
    the http://www.w3.org/Protocols/rfc2616/rfc2616-sec2.html#sec2.1 (with
    the notable exception that white-space is significant here) the
    expression syntax expected by the "->parse" method can be defined like
    this:

        expression =
           segment *( brace-expression segment )

    A *segment* is a sequence of zero or more characters or
    escaped-characters (i.e. braces and commas must be escaped with a
    preceding backslash).

        segment =
           *( escaped-character | <any character except glob-characters> )

    Where:

        escaped-character =
           "\" <any char>

        glob-character =
           "{" | "}" | ","

    A *brace-expression* is a sequence of one or more *expressions* (which
    in this context I call 'alternatives'), delimited by commas, and
    enclosed in braces.

        brace-expression =
           "{" expression ( "," expression )* "}"

OBJECT STRUCTURE
    An expression such as described in the previous above is parsed into an
    arrayref of text *segments* (represented with
    "Text::Glob::Expand::Segment" instances) and *brace-expressions*
    (represented by arrayrefs).

    An *expression* is represented at the top level by a
    "Text::Glob::Expand" instance, which is a blessed arrayref containing
    only "Text::Glob::Expand::Segment" instances and *brace-expression*
    arrayrefs.

    Each *brace-expression* array contains a list of the brace-expression's
    'alternatives' (the comma-delimited sub-expressions within the braces).
    These are represented by arrayrefs. Apart from being unblessed, they
    otherwise have the same structure as the top-level expression.

    "Text::Glob::Expand::Segment" instances are blessed arrayrefs, composed
    of a string plus an integer (>= 0) indicating the number of brace-pairs
    enclosing the segment. The depth is used internally to preserve the
    expression structure, and may be ignored by the user. (See also
    Text::Glob::Expand::Segment.)

    For example, an expression such as:

        "a{b,{c,d}e,}g"

    Will be parsed into something analogous to this structure (for better
    readability I use a simplified Perl data-structure in which segments are
    represented by simple strings instead of blessed arrays, and use
    comments to denote types):

        [ # expression
          'a', # segment depth 0
          [ # brace
            [ # expression
              'b' # segment, depth 1
            ],
            [ # expression
              '', # segment, depth 1
              [ # brace
                [ # expression
                  'c' # segment, depth 2
                ],
                [ # expression
                  'd' # segment, depth 2
                ],
              ],
              'e' # segment, depth 1
            ],
            [ # expression
              '' # segment, depth 1
            ]
          ],
          'g', # segment, depth 0
        ]

DIAGNOSTICS
    The following parsing diagnostics should never actually occur. If they
    do it means the internal data structure or code design is inconsistent.
    In this case, please file a bug report with details of how to replicate
    the error.

    "unexpected scalar..."
    "no such state..."
    "no handler for state '...' looking at '...' pos '...'"

CONFIGURATION AND ENVIRONMENT
    "Text::Glob::Expand" requires no configuration files or environment
    variables.

    There is one configurable option in the form of a package variable, as
    follows.

  $MAX_CACHING
    The package variable $Text::Glob::Expand::MAX_CACHING can be used to
    control or disable the caching done by the "->explode" method. It should
    be a positive integer, or zero.

    The default value is 100, which means that up to 100
    "Text::Glob::Expand" objects' "->explode" results will be cached, but no
    more. You can disable caching by setting this to zero or less.

DEPENDENCIES
    The dependencies should be minimal - I aim to have none.

    For a definitive answer, see the Build.PL file included in the
    distribution, or use the dependencies tool on <http://search.cpan.org>

BUGS AND LIMITATIONS
    Currently the parser will infer closing brackets at the end of an
    expression if they are omitted. Probably a syntax error should be thrown
    instead.

    Also, extra closing brackets with no matching opening bracket will
    generate an error. This is a bug which will be addressed in future
    versions.

    Please report any bugs or feature requests to
    "bug-Text-Glob-Expand@rt.cpan.org", or through the web interface at
    <http://rt.cpan.org>.

SEE ALSO
    Similar libraries I am aware of are:

    Text::Glob
        Wildcard matching against strings, which includes alternation (brace
        expansion).

    String::Glob::Permute
        A permutation generator similar to this one. Supports numbered
        ranges, but not format string expansion.

    Plus there is of course Perl's own "glob" function, which supports brace
    expansions. That however can be sensitive to unusually-named files in
    the current director - and more importantly, like
    "String::Glob::Permute" it does not implement format string expansions.

AUTHOR
    Nick Stokoe "<wulee@cpan.org>"

LICENCE AND COPYRIGHT
    Copyright (c) 2011, Nick Stokoe "<wulee@cpan.org>". All rights reserved.

    This module is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself. See perlartistic.

DISCLAIMER OF WARRANTY
    BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
    FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
    OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
    PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
    EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
    ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
    YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
    NECESSARY SERVICING, REPAIR, OR CORRECTION.

    IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
    WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
    REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
    TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
    CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
    SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
    RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
    FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
    SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
    DAMAGES.

