List-Maker-v0.0.5/0000755000076500007650000000000010756724472013146 5ustar damiandamianList-Maker-v0.0.5/Build.PL0000644000076500007650000000071210626173232014426 0ustar damiandamianuse strict; use warnings; use Module::Build; my $builder = Module::Build->new( module_name => 'List::Maker', license => 'perl', dist_author => 'Damian Conway ', dist_version_from => 'lib/List/Maker.pm', requires => { 'Test::More' => 0, 'File::Glob' => 0, 'version' => 0, }, add_to_cleanup => [ 'List-Maker-*' ], ); $builder->create_build_script(); List-Maker-v0.0.5/Changes0000644000076500007650000000076410756724460014445 0ustar damiandamianRevision history for List-Maker 0.0.1 Tue Oct 18 22:54:56 2005 Initial release. 0.0.2 Fri Feb 17 17:02:57 2006 No changes logged 0.0.3 Wed Mar 8 10:28:42 2006 * Added missing README synopsis (thanks Colin) 0.0.4 Sat Feb 9 11:08:51 2008 * Made globbing magical only in those source files that explicitly load the module (thanks Steffen) * Documented , , and <^N> syntaxes 0.0.5 Wed Feb 20 15:14:40 2008 * Added in missing test module List-Maker-v0.0.5/lib/0000755000076500007650000000000010756724472013714 5ustar damiandamianList-Maker-v0.0.5/lib/List/0000755000076500007650000000000010756724472014627 5ustar damiandamianList-Maker-v0.0.5/lib/List/Maker/0000755000076500007650000000000010756724472015666 5ustar damiandamianList-Maker-v0.0.5/lib/List/Maker/OtherModule.pm0000644000076500007650000000047710753165620020452 0ustar damiandamianpackage List::Maker::OtherModule; use warnings; use strict; use Carp; use version; our $VERSION = qv('0.0.1'); sub _regular_glob { my @data = <1..10>; return @data != 10; } package main; sub _regular_glob { my @data = <1..10>; return @data != 10; } 1; # Magic true value required at end of module List-Maker-v0.0.5/lib/List/Maker.pm0000644000076500007650000004111610756724460016224 0ustar damiandamianpackage List::Maker; use version; $VERSION = qv('0.0.5'); use warnings; use strict; use Carp; # Handle contextual returns sub _context { # Return original list in list context... return @_ if (caller 1)[5]; # Otherwise, Anglicize list... return "" if @_ == 0; return "$_[0]" if @_ == 1; return "$_[0] and $_[1]" if @_ == 2; my $sep = grep(/,/, @_) ? q{; } : q{, }; return join($sep, @_[0..@_-2]) . $sep . "and $_[-1]"; } # Regexes to parse the acceptable list syntaxes... my $NUM = qr{\s* [+-]? \d+ (?:\.\d*)? \s* }xms; my $TO = qr{\s* \.\. \s*}xms; my $FILTER = qr{ (?: : (.*) )? }xms; my @handlers = ( # <1, 2 .. 10> { pat => qr{\A ($NUM) , ($NUM) ,? $TO (\^?) ($NUM) $FILTER \Z}xms, gen => sub{ _gen_range( {from=>$1, to=>$4, by=>$2-$1, filter=>$5, exto=>$3} ); }, }, # <1 .. 10 by 2> { pat => qr{\A ($NUM) (\^?) $TO (\^?) ($NUM) (?:(?:x|by) ($NUM))? $FILTER \Z}xms, gen => sub{ _gen_range( {from=>$1, to=>$4, by=>$5, filter=>$6, exfrom=>$2, exto=>$3} ); }, }, # <^7 by 2> { pat => qr{\A \s* \^ ($NUM) \s* (?:(?:x|by) \s* ($NUM))? $FILTER \Z}xms, gen => sub{ _gen_range( {from=>0, to=>$1, by=>$2, filter=>$3, exto=>1} ); }, }, # <^@foo> { pat => qr{\A \s* \^ \s* ( (?:\S+\s+)* \S+) \s* \Z}xms, gen => sub{ my @array = split /\s+/, $1; _gen_range( {from=>0, to=>@array-1}); }, }, # MINrMAX random range notation { pat => qr/^\s* ([+-]?\d+(?:[.]\d*)?|[.]\d+) \s* r \s* ([+-]?\d+(?:[.]\d*)?|[.]\d+) \s* $/xms, gen => sub { my ($min, $max) = ($1 < $2) ? ($1,$2) : ($2,$1); return $min + rand($max - $min); } }, # NdS dice notation { pat => qr/^\s* (\d+(?:[.]\d*)?|[.]\d+) \s* d \s* (\d+(?:[.]\d*)?|[.]\d+) \s* $/xms, gen => sub { my ($count, $sides) = ($1, $2); # Non-integer counts require an extra random (partial) value... if ($count =~ /[.]/) { $count++; } # Generate random values... my @rolls = $sides =~ /[.]/ ? map { rand $sides} 1..$count : map {1 + int rand $sides} 1..$count ; # Handle a non-integer count by scaling final random (partial) value... if ($count =~ /([.].*)/) { my $fraction = $1; $rolls[-1] *= $fraction; } return @rolls if wantarray; use List::Util qw( sum ); return sum @rolls; } }, # Perl 6 xx operator on 'strings'... { pat => qr/^ \s* ' ( [^']* ) ' \s* xx \s* (\d+) \s* $/xms, gen => sub { my ($string, $repetitions) = ($1, $2); return ($string) x $repetitions; } }, # Perl 6 xx operator on "strings"... { pat => qr/^ \s* " ( [^"]* ) " \s* xx \s* (\d+) \s* $/xms, gen => sub { my ($string, $repetitions) = ($1, $2); return ($string) x $repetitions; } }, # Perl 6 xx operator on numbers... { pat => qr/^ \s* ( [+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)? ) \s* xx \s* (\d+) \s* $/xms, gen => sub { my ($number, $repetitions) = ($1, $2); return (0+$number) x $repetitions; } }, ); my %caller_expecting_special_behaviour; my @user_handlers; # This does the magic... my $list_maker_sub = sub { my ($listspec) = @_; # If it doesn't match a special form, it's a < word list >... for my $handler (@user_handlers, @handlers) { next if $listspec !~ m{$handler->{pat}}xms; return $handler->{gen}(); } return _context _qww($listspec); }; sub import { shift; # Don't need package name # Explicit export requested if (@_) { my $caller = caller; for my $name (@_) { no strict 'refs'; *{$caller.'::'.$name} = $list_maker_sub; } } else { my ($package, $file) = caller; $caller_expecting_special_behaviour{ $package, $file } = 1; } } sub add_handler { while (my ($regex, $sub) = splice @_, 0, 2) { croak "Usage: List::Make::add_handler(qr/.../, sub{...})\nError" if ref($regex) ne 'Regexp' || ref($sub) ne 'CODE'; push @user_handlers, { pat=>$regex, gen=>$sub }; } return; } no warnings 'redefine'; *CORE::GLOBAL::glob = sub { # Don't be magical in those files that haven't loaded the module... my ($package, $file) = caller; if (!$caller_expecting_special_behaviour{$package, $file}) { use File::Glob; goto &File::Glob::bsd_glob } else { goto &{$list_maker_sub}; } }; sub _gen_range { my ($from, $to, $incr, $filter, $exfrom, $exto) = @{shift()}{ qw }; s/^ \s+ | \s+ $//gxms for $from, $to; if (!defined $incr) { $incr = -($from <=> $to); } # Check for nonsensical increments (zero or the wrong sign)... my $delta = $to - $from; croak sprintf "Sequence <%s, %s, %s...> will never reach %s", $from, $from+$incr, $from+2*$incr, $to if $incr == 0 && $from != $to || $delta * $incr < 0; # Generate unfiltered list of values... $from += $incr if $exfrom; my @vals; if ($incr==0) { @vals = $exto || $exfrom ? () : $from; } elsif ($incr>0) { while (1) { last if $exto && ($from >= $to || $from eq $to) || !$exto && $from > $to; push @vals, $from; $from += $incr; } } elsif ($incr<0) { while (1) { last if $exto && ($from <= $to || $from eq $to) || !$exto && $from < $to; push @vals, $from; $from += $incr; } } # Apply any filter before returning the values... if (defined $filter) { (my $trans_filter = $filter) =~ s/\b[A-Z]\b/\$_/g; @vals = eval "grep {package ".caller(2)."; $trans_filter } \@vals"; croak "Bad filter ($filter): $@" if $@; } return @vals; }; sub _qww { my ($content) = @_; # Break into words (or "w o r d s" or 'w o r d s') and strip quoters... return map { !defined($_) ? () : $_ } $content =~ m{ " ( [^\\"]* (?:\\. [^\\"]*)* ) " | ' ( [^\\']* (?:\\. [^\\']*)* ) ' | ( \S+ ) }gxms; } 1; # Magic true value required at end of module __END__ =head1 NAME List::Maker - Generate more sophisticated lists than just $a..$b =head1 VERSION This document describes List::Maker version 0.0.5 =head1 SYNOPSIS use List::Maker; @list = <1..10>; # (1,2,3,4,5,6,7,8,9,10) @list = <10..1>; # (10,9,8,7,6,5,4,3,2,1) @list = <1,3,..10>; # (1,3,5,7,9) @list = <1..10 x 2>; # (1,3,5,7,9) @list = <0..10 : prime N>; # (2,3,5,7) @list = <1,3,..30 : /7/>; # (7,17,27) @list = < ^10 >; # (0,1,2,3,4,5,6,7,8,9) @list = < ^@array >; # (0..$#array) @words = < a list of words >; # ('a', 'list', 'of', 'words') @words = < 'a list' "of words" >; # ('a list', 'of words') use List::Maker 'listify'; @list = listify '1..10'; # (1,2,3,4,5,6,7,8,9,10) use List::Maker 'make_list'; @list = make_list '10..1'; # (10,9,8,7,6,5,4,3,2,1) use List::Maker 'ql'; @list = ql'1..10 x 2'; # (1,3,5,7,9) =head1 DESCRIPTION The List::Maker module hijacks Perl's built-in file globbing syntax (C<< < *.pl > >> and C) and retargets it at list creation. The rationale is simple: most people rarely if ever glob a set of files, but they have to create lists in almost every program they write. So the list construction syntax should be easier than the filename expansion syntax. Alternatively, you can load the module with an explicit name, and it creates a subroutine of that name that builds the same kinds of lists for you (leaving the globbing mechanism unaltered). =head1 INTERFACE Within any file in which the module has been explicitly loaded: use List::Maker; angle brackets no longer expand a shell pattern into a list of files. Instead, they expand a list specification into a list of values. =head2 Numeric lists Numeric list specifications may take any of the following forms: Type Syntax For example Produces ========== =================== =========== =========== Count up <1..5> (1,2,3,4,5) Count down <5..1> (5,4,3,2,1) Count to < ^LIMIT > < ^5 > (0,1,2,3,4) Count by <1..10 x 3> (1,4,7,10) Count via <1, 3,..10> (1,3,5,7,9) The numbers don't have to be integers either: @scores = <0.5..4.5>; # same as: (0.5, 1.5, 2.5, 3.5, 4.5) @steps = <1..0 x -0.2>; # same as: (1, 0.8, 0.6, 0.4, 0.2, 0) =head2 Filtered numeric lists Any of the various styles of numeric list may also have a filter applied to it, by appending a colon, followed by a boolean expression: @odds = <1..100 : \$_ % 2 != 0 >; @primes = <3,5..99> : is_prime(\$_) >; @available = < ^$max : !allocated{\$_} > @ends_in_7 = <1..1000 : /7$/ > The boolean expression is tested against each element of the list, and only those for which it is true are retained. During these tests each element is aliased to C<$_>. However, since angle brackets interpolate, it's necessary to escape any explicit reference to C<$_> within the filtering expression, as in the first three examples above. That often proves to be annoying, so the module also allows the candidate value to be referred to using any single uppercase letter (which is replaced with C<\$_> when the filter is applied. So the previous examples could also be written: @odds = <1..100 : N % 2 != 0 >; @primes = <3,5..99> : is_prime(N) >; @available = < ^$max : !allocated{N} > or (since the specific letter is irrelevant): @odds = <1..100 : X % 2 != 0 >; @primes = <3,5..99> : is_prime(I) >; @available = < ^$max : !allocated{T} > =head2 String lists Any list specification that doesn't conform to one of the four pattern described above is taken to be a list of whitespace-separated strings, like a C list: @words = ; # same as: ( 'Eat', 'at', 'Joe\'s' ) However, unlike a C, these string lists interpolate (before listification): $whose = q{Joe's}; @words = ; # same as: ( 'Eat', 'at', 'Joe\'s' ) More interestingly, the words in these lists can be quoted to change the default whitespace separation. For example: @names = ; # same as: ( 'Tom', 'Dick', 'Harry Potter' ) Single quotes may be also used, but this may be misleading, since the overall list still interpolates in that case: @names = ; # same as: ( 'Tom', 'Dick', "$Harry{Potter}" ) In a scalar context, any string list is converted to the standard English representation: $names = ; # 'Tom' $names = ; # 'Tom and Dick' $names = ; # 'Tom, Dick, and Harry Potter' =head2 Perl 6 repetition list operator List::Maker also understands the Perl 6 C listification operator: @affirmations = <'aye' xx 5>; # ('aye','aye','aye','aye','aye') =head2 Random number generation The module understands two syntaxes for generating random numbers. It can generate a random number within a range: $random = < 2r5.5 >; # 2 <= Random number < 5.5 It can also generate an "NdS" dice roll (i.e. the sum of rolling N dice, each with S sides): $roll = < 3d12 >; # Sum of three 12-sided dice The dice notation cares nothing for the laws of physics or rationality and so it will even allow you to specify a non-integer number of "fractal dice", each with an non-integer numbers of sides: $roll = < 3.7d12.3 >; # Sum of three-point-seven 12.3-sided dice In a list context, the dice notation returns the results of each of the individual die rolls (including the partial result of a "fractal" roll) @rolls = < 3d12 >; # (6, 5, 12) @rolls = < 3.7d12.3 >; # (6.1256, 5.9876, 12.0012, 0.3768) The values returned in list context will always add up to the value that would have been returned in a scalar context. =head2 User-defined syntax via C You can add new syntax variations to the C<< <...> >> format using the C function: add_handler($pattern => $sub_ref, $pattern => $sub_ref...); Each pattern is added to the list of syntax checkers and, if it matches, the corresponding subroutine is called to furnish the result of the C<< <...> >>. User-defined handlers are tested in the same order that they are defined, but I the standard built-in formats described above. =head1 ALTERNATE INTERFACE If an argument is passed to the C statement, then that argument is used as the name of a subroutine to be installed in the current package. That subroutine then expects a single argument, which may be used to generate any of the lists described above. In other words, passing an argument to C creates an explicit list-making subroutine, rather than hijacking the built-in C<< <..> >> and C. For example: use List::Maker 'range'; for (range '1..100 x 5') { print "$_: $result{$_}\n"; } use List::Maker 'roll'; if (roll '3d12' > 20) { print "The $creature hits you\n"; } use List::Maker 'conjoin'; print conjoin @names; =head1 DIAGNOSTICS =over =item C<< Sequence <%s, %s, %s...> will never reach %s >> The specified numeric list didn't make sense. Typically, because you specified an increasing list with a negative step size (or vice versa). =back =head1 CONFIGURATION AND ENVIRONMENT List::Maker requires no configuration files or environment variables. =head1 DEPENDENCIES None. =head1 INCOMPATIBILITIES Using this module normally prevents you from using the built-in behaviours of C<< <...> >> or C in any files that directly C the module (though files that don't load the module are unaffected). In files that use the module, you would need to use the C module directly: use File::Glob; my @files = bsd_glob("*.pl"); Alternatively, export the list maker by name (see L<"ALTERNATE INTERFACE">). =head1 BUGS AND LIMITATIONS The lists generated are not lazy. So this: for (<1..10000000>) { ... } will be vastly slower than: for (1..10000000) { ... } Please report any bugs or feature requests to C, or through the web interface at L. =head1 AUTHOR Damian Conway C<< >> =head1 LICENCE AND COPYRIGHT Copyright (c) 2005, Damian Conway C<< >>. All rights reserved. This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See L. =head1 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. List-Maker-v0.0.5/Makefile.PL0000644000076500007650000000103110626173237015104 0ustar damiandamianuse strict; use warnings; use ExtUtils::MakeMaker; WriteMakefile( NAME => 'List::Maker', AUTHOR => 'Damian Conway ', VERSION_FROM => 'lib/List/Maker.pm', ABSTRACT_FROM => 'lib/List/Maker.pm', PL_FILES => {}, PREREQ_PM => { 'Test::More' => 0, 'File::Glob' => 0, 'version' => 0, }, dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, clean => { FILES => 'List-Maker-*' }, ); List-Maker-v0.0.5/MANIFEST0000644000076500007650000000053510756724436014302 0ustar damiandamianBuild.PL Changes MANIFEST META.yml # Will be created by "make dist" Makefile.PL README lib/List/Maker.pm lib/List/Maker/OtherModule.pm t/00.load.t t/error.t t/filter.t t/interp.t t/pod-coverage.t t/pod.t t/range.t t/range_by.t t/tri_range.t t/wordlist.t t/dice.t t/modules.t t/named_range_by.t t/rand_range.t t/unary_range.t t/user_defined.t t/xx.t List-Maker-v0.0.5/META.yml0000644000076500007650000000064110756724472014420 0ustar damiandamian# http://module-build.sourceforge.net/META-spec.html #XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# name: List-Maker version: v0.0.5 version_from: lib/List/Maker.pm installdirs: site requires: File::Glob: 0 Test::More: 0 version: 0 distribution_type: module generated_by: ExtUtils::MakeMaker version 6.30 List-Maker-v0.0.5/README0000644000076500007650000000264110756724460014026 0ustar damiandamianList::Maker version 0.0.5 The List::Maker module hijacks Perl's built-in file globbing syntax ("< *.pl >" and "glob '*.pl'") and retargets it at list creation. The rationale is simple: most people rarely if ever glob a set of files, but they have to create lists in almost every program they write. So the list construction syntax should be easier than the file-name expansion syntax. use List::Maker; @list = <1..10>; # (1,2,3,4,5,6,7,8,9,10) @list = <10..1>; # (10,9,8,7,6,5,4,3,2,1) @list = <1,3,..10> # (1,3,5,7,9) @list = <1..10 x 2> # (1,3,5,7,9) @list = <0..10 : prime N>; # (2,3,5,7) @list = <1,3,..30 : /7/> # (7,17,27) @words = < a list of words >; # ('a', 'list', 'of', 'words') @words = < 'a list' "of words" >; # ('a list', 'of words') INSTALLATION To install this module, run the following commands: perl Makefile.PL make make test make install Alternatively, to install with Module::Build, you can use the following commands: perl Build.PL ./Build ./Build test ./Build install DEPENDENCIES None. COPYRIGHT AND LICENCE Copyright (C) 2005, Damian Conway This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. List-Maker-v0.0.5/t/0000755000076500007650000000000010756724472013411 5ustar damiandamianList-Maker-v0.0.5/t/00.load.t0000644000076500007650000000016510753161570014724 0ustar damiandamianuse Test::More tests => 1; BEGIN { use_ok( 'List::Maker' ); } diag( "Testing List::Maker $List::Maker::VERSION" ); List-Maker-v0.0.5/t/dice.t0000644000076500007650000000150010753165354014471 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker; for (1..100) { my $roll = < 2 d 7 >; ok $roll >= 2 && $roll <= 14 => "< 2 d 7 > roll $_ ($roll)"; } for (1..100) { my $roll = < 7d2 >; ok $roll >= 7 && $roll <= 14 => "< 7d2 > roll $_ ($roll)"; } for (1..100) { my $roll = < 3d4.0 >; ok $roll >= 0 && $roll < 12 => "< 3d4.0 > roll $_ ($roll)"; } for (1..100) { my @rolls = < 3 d 12 >; is scalar @rolls, 3 => 'list context count'; for my $roll (@rolls) { ok $roll >= 1 && $roll <= 12 => "list context element ($roll)"; } } for (1..100) { my @rolls = < 3.7 d 12.3 >; is scalar @rolls, 4 => 'list context count'; for my $roll (@rolls) { ok $roll >= 0 && $roll < 12.3 => "list context element ($roll)"; } } List-Maker-v0.0.5/t/error.t0000644000076500007650000000151710452453364014723 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker; sub test (&@) { my ($test, $desc) = @_; my ($res) = eval { $test->(); 1; }; like $@, qr/\A$desc/ => $desc; } test { <1..10 x -1> } 'Sequence <1, 0, -1...> will never reach 10'; test { <1..-10 x 1> } 'Sequence <1, 2, 3...> will never reach -10'; test { <1,3..-10> } 'Sequence <1, 3, 5...> will never reach -10'; test { <1,-2..10> } 'Sequence <1, -2, -5...> will never reach 10'; test { <1,1..10> } 'Sequence <1, 1, 1...> will never reach 10'; test { <2..10x0> } 'Sequence <2, 2, 2...> will never reach 10'; test { <3,3..-10> } 'Sequence <3, 3, 3...> will never reach -10'; test { <4..-10x0> } 'Sequence <4, 4, 4...> will never reach -10'; is_deeply [<1,1..1>], [1] => 'Sequence <1, 1, 1...> will reach 1'; is_deeply [<2..2x0>], [2] => 'Sequence <2, 2, 2...> will reach 2'; List-Maker-v0.0.5/t/filter.t0000644000076500007650000000065310451505765015061 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker; sub odd { shift() % 2 } is_deeply [<1..10 : odd X>], [1,3,5,7,9] => '<1..10 : odd X>'; is_deeply [<1..10x3 : odd N>], [1,7] => '<1..10x3 : odd N>'; is_deeply [<1,5..10 : odd I>], [1,5,9] => '<1,5..10 : odd I>'; is_deeply [<1,5..10 : odd \$_>], [1,5,9] => '<1,5..10 : odd \\$_>'; is_deeply [<1..20 : /7/>], [7,17] => '<1..20 : /7/>'; List-Maker-v0.0.5/t/interp.t0000644000076500007650000000072310451510420015053 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker; my ($from, $to, $by) = (1,10,2); is_deeply [<$to..$from>], [10,9,8,7,6,5,4,3,2,1] => '<$to..$from>'; is_deeply [<$from..$to x $by>], [1,3,5,7,9] => '<$from..$to x $by>'; is_deeply [<$from, $by..$to>], [1..10] => '<$from, $by,..$to>'; is_deeply [<10..$from>], [10,9,8,7,6,5,4,3,2,1] => '<10..$from>'; my $range = '2..7x2'; is_deeply [< $range >], [2,4,6] => '< $range >'; List-Maker-v0.0.5/t/modules.t0000644000076500007650000000072410753165673015250 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker::OtherModule; use List::Maker; # INCLUSIVE... is_deeply [<1..10>], [1,2,3,4,5,6,7,8,9,10] => '<1..10>'; is_deeply [<9.9..1.1>], [map { 10-$_+0.9 } 1..9] => '<9.9..1.1>'; ok List::Maker::OtherModule::_regular_glob() => 'Ignored in other modules'; ok main::_regular_glob() => 'Ignored in other files'; package Elsewhere; my @data = <1..10>; ::ok @data != 10, 'Ignored in other packages'; List-Maker-v0.0.5/t/named_range_by.t0000644000076500007650000000321010753164734016520 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker 'list'; is_deeply [list '1..10x1'], [1,2,3,4,5,6,7,8,9,10] => '<1..10x1>'; is_deeply [list '1..10 x1'], [1,2,3,4,5,6,7,8,9,10] => '<1..10 x1>'; is_deeply [list '1..10x 1'], [1,2,3,4,5,6,7,8,9,10] => '<1..10x 1>'; is_deeply [list '1..10 x 1'], [1,2,3,4,5,6,7,8,9,10] => '<1..10 x 1>'; is_deeply [list '-1..10x1'], [-1,0,1,2,3,4,5,6,7,8,9,10] => '<-1..10>'; is_deeply [list '1..1x1'], [1] => '<1..1>'; is_deeply [list '1..1x2'], [1] => '<1..1>'; is_deeply [list '10..1x-1'], [10,9,8,7,6,5,4,3,2,1] => '<10..1>'; is_deeply [list '1.1..9.9x1'], [map { $_+0.1 } 1..9] => '<1.1..9.9x1>'; is_deeply [list '9.9..1.1x-1'], [map { 10-$_+0.9 } 1..9] => '<9.9..1.1x-1>'; is_deeply [list '1..10x2'], [1,3,5,7,9] => '<1..10x2>'; is_deeply [list '1..10x3'], [1,4,7,10] => '<1..10x3>'; is_deeply [list '1..10x4'], [1,5,9] => '<1..10x4>'; is_deeply [list '1..10x5'], [1,6] => '<1..10x5>'; is_deeply [list '1..10x6'], [1,7] => '<1..10x6>'; is_deeply [list '1..10x7'], [1,8] => '<1..10x7>'; is_deeply [list '1..10x8'], [1,9] => '<1..10x8>'; is_deeply [list '1..10x9'], [1,10] => '<1..10x9>'; is_deeply [list '1..10x10'], [1] => '<1..10x10>'; is_deeply [list '1.1..9.9x2.5'], [1.1, 3.6, 6.1, 8.6] => '<1.1..9.9x2.5>'; # Verify that no magic is occurring... my @data = <1..10>; ok @data != 10, 'No magic'; List-Maker-v0.0.5/t/pod-coverage.t0000644000076500007650000000032310753161677016146 0ustar damiandamianuse Test::More; eval "use Test::Pod::Coverage 1.04"; if ($@) { plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" } else { plan 'no_plan'; } pod_coverage_ok( 'List::Maker' ); List-Maker-v0.0.5/t/pod.t0000644000076500007650000000021410325170240014331 0ustar damiandamian#!perl -T use Test::More; eval "use Test::Pod 1.14"; plan skip_all => "Test::Pod 1.14 required for testing POD" if $@; all_pod_files_ok(); List-Maker-v0.0.5/t/rand_range.t0000644000076500007650000000043010753162776015673 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker; for (1..100) { my $rand = < 2 r 7 >; ok $rand >= 2 && $rand <= 7 => "< 2 r 7 > rand $_ ($rand)"; } for (1..100) { my $rand = < -2.2 r .7 >; ok $rand >= -2.2 && $rand <= 0.7 => "< -2.2 r .7 > rand $_ ($rand)"; } List-Maker-v0.0.5/t/range.t0000644000076500007650000000431010452455406014657 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker; # INCLUSIVE... is_deeply [<1..10>], [1,2,3,4,5,6,7,8,9,10] => '<1..10>'; is_deeply [<-1..10>], [-1,0,1,2,3,4,5,6,7,8,9,10] => '<-1..10>'; is_deeply [<1..1>], [1] => '<1..1>'; is_deeply [<10..1>], [10,9,8,7,6,5,4,3,2,1] => '<10..1>'; is_deeply [<1.1..9.9>], [map { $_+0.1 } 1..9] => '<1.1..9.9>'; is_deeply [<9.9..1.1>], [map { 10-$_+0.9 } 1..9] => '<9.9..1.1>'; # PRE EXCLUSIVE... is_deeply [<1^..10>], [2,3,4,5,6,7,8,9,10] => '<1^..10>'; is_deeply [<-1^..10>], [0,1,2,3,4,5,6,7,8,9,10] => '<-1^..10>'; is_deeply [<1^..1>], [] => '<1^..1>'; is_deeply [<10^..1>], [9,8,7,6,5,4,3,2,1] => '<10^..1>'; is_deeply [1.1, <1.1^..9.9>], [map { $_+0.1 } 1..9] => '<1.1^..9.9>'; is_deeply [9.9, <9.9^..1.1>], [map { 10-$_+0.9 } 1..9] => '<9.9^..1.1>'; # POST EXCLUSIVE... is_deeply [<1..^10>], [1,2,3,4,5,6,7,8,9] => '<1..^10>'; is_deeply [<-1..^10>], [-1,0,1,2,3,4,5,6,7,8,9] => '<-1..^10>'; is_deeply [<1..^1>], [] => '<1..^1>'; is_deeply [<10..^1>], [10,9,8,7,6,5,4,3,2] => '<10..^1>'; is_deeply [<1.1..^9.9>], [map { $_+0.1 } 1..9] => '<1.1..^9.9>'; is_deeply [<9.9..^1.1>], [map { 10-$_+0.9 } 1..9] => '<9.9..^1.1>'; is_deeply [<1.1..^9.1>], [map { $_+0.1 } 1..8] => '<1.1..^9.1>'; is_deeply [<9.9..^1.9>], [map { 10-$_+0.9 } 1..8] => '<9.9..^1.9>'; # PRE/POST EXCLUSIVE... is_deeply [<1^..^10>], [2,3,4,5,6,7,8,9] => '<1^..^10>'; is_deeply [<-1^..^10>], [0,1,2,3,4,5,6,7,8,9] => '<-1^..^10>'; is_deeply [<1^..^1>], [] => '<1^..^1>'; is_deeply [<10^..^1>], [9,8,7,6,5,4,3,2] => '<10^..^1>'; is_deeply [<1.1^..^9.9>], [map { $_+0.1 } 2..9] => '<1.1^..^9.9>'; is_deeply [<9.9^..^1.1>], [map { 10-$_+0.9 } 2..9] => '<9.9^..^1.1>'; is_deeply [<1.1^..^9.1>,9.1], [map { $_+0.1 } 2..9] => '<1.1^..^9.9>'; is_deeply [<9.9^..^1.9>,1.9], [map { 10-$_+0.9 } 2..9] => '<9.9^..^1.1>'; List-Maker-v0.0.5/t/range_by.t0000644000076500007650000000270510451501400015340 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker; is_deeply [<1..10x1>], [1,2,3,4,5,6,7,8,9,10] => '<1..10x1>'; is_deeply [<1..10 x1>], [1,2,3,4,5,6,7,8,9,10] => '<1..10 x1>'; is_deeply [<1..10x 1>], [1,2,3,4,5,6,7,8,9,10] => '<1..10x 1>'; is_deeply [<1..10 x 1>], [1,2,3,4,5,6,7,8,9,10] => '<1..10 x 1>'; is_deeply [<-1..10x1>], [-1,0,1,2,3,4,5,6,7,8,9,10] => '<-1..10>'; is_deeply [<1..1x1>], [1] => '<1..1>'; is_deeply [<1..1x2>], [1] => '<1..1>'; is_deeply [<10..1x-1>], [10,9,8,7,6,5,4,3,2,1] => '<10..1>'; is_deeply [<1.1..9.9x1>], [map { $_+0.1 } 1..9] => '<1.1..9.9x1>'; is_deeply [<9.9..1.1x-1>], [map { 10-$_+0.9 } 1..9] => '<9.9..1.1x-1>'; is_deeply [<1..10x2>], [1,3,5,7,9] => '<1..10x2>'; is_deeply [<1..10x3>], [1,4,7,10] => '<1..10x3>'; is_deeply [<1..10x4>], [1,5,9] => '<1..10x4>'; is_deeply [<1..10x5>], [1,6] => '<1..10x5>'; is_deeply [<1..10x6>], [1,7] => '<1..10x6>'; is_deeply [<1..10x7>], [1,8] => '<1..10x7>'; is_deeply [<1..10x8>], [1,9] => '<1..10x8>'; is_deeply [<1..10x9>], [1,10] => '<1..10x9>'; is_deeply [<1..10x10>], [1] => '<1..10x10>'; is_deeply [<1.1..9.9x2.5>], [1.1, 3.6, 6.1, 8.6] => '<1.1..9.9x2.5>'; List-Maker-v0.0.5/t/tri_range.t0000644000076500007650000000534010451505521015532 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker; is_deeply [<1,2..10>], [1,2,3,4,5,6,7,8,9,10] => '<1,2..10>'; is_deeply [<1,2,..10>], [1,2,3,4,5,6,7,8,9,10] => '<1,2,..10>'; is_deeply [<1, 2 .. 10>], [1,2,3,4,5,6,7,8,9,10] => '<1, 2 .. 10>'; is_deeply [<-1,0..10>], [-1,0,1,2,3,4,5,6,7,8,9,10] => '<-1,0..10>'; is_deeply [<1,1,..1>], [1] => '<1,1,..1>'; is_deeply [<1,2,..1>], [1] => '<1,2,..1>'; is_deeply [<10,9..1>], [10,9,8,7,6,5,4,3,2,1] => '<10,9..1>'; is_deeply [<1.1,2.1..9.9>], [map { $_+0.1 } 1..9] => '<1.1,2.1..9.9>'; is_deeply [<9.9,8.9..1.1>], [map { 10-$_+0.9 } 1..9] => '<9.9,8.9..1.1x-1>'; is_deeply [<1,3..10>], [1,3,5,7,9] => '<1,3..10>'; is_deeply [<1,4..10>], [1,4,7,10] => '<1,4..10>'; is_deeply [<1,5..10>], [1,5,9] => '<1,5..10>'; is_deeply [<1,6..10>], [1,6] => '<1,6..10>'; is_deeply [<1,7..10>], [1,7] => '<1,7..10>'; is_deeply [<1,8..10>], [1,8] => '<1,8..10>'; is_deeply [<1,9..10>], [1,9] => '<1,9..10>'; is_deeply [<1,10..10>], [1,10] => '<1,10..10>'; is_deeply [<1.1,3.6,..9.9>], [1.1, 3.6, 6.1, 8.6] => '<1.1,3.6,..9.9>'; # EXCLUSIVE... # is_deeply [<1,2..^10>], [1,2,3,4,5,6,7,8,9] => '<1,2..^10>'; is_deeply [<1,2,..^10>], [1,2,3,4,5,6,7,8,9] => '<1,2,..^10>'; is_deeply [<1, 2 ..^ 10>], [1,2,3,4,5,6,7,8,9] => '<1, 2 ..^10>'; is_deeply [<-1,0..^10>], [-1,0,1,2,3,4,5,6,7,8,9] => '<-1,0..^10>'; is_deeply [<1,1,..^1>], [] => '<1,1..^1>'; is_deeply [<1,2,..^1>], [] => '<1,2..^1>'; is_deeply [<10,9..^1>], [10,9,8,7,6,5,4,3,2] => '<10,9..^1>'; is_deeply [<1.1,2.1..^9.9>], [map { $_+0.1 } 1..9] => '<1.1,2.1..^9.9>'; is_deeply [<9.9,8.9..^1.1>], [map { 10-$_+0.9 } 1..9] => '<9.9,8.9..^1.1>'; is_deeply [<1.1,2.2..^9.9>], [map { $_*1.1 } 1..8] => '<1.1,2.2..^9.9>'; is_deeply [<9.9,8.8..^1.1>], [map { 9.9-$_*1.1 } 0..7] => '<9.9,8.8..^1.1>'; is_deeply [<1,3..^10>], [1,3,5,7,9] => '<1,3..^10>'; is_deeply [<1,4..^10>], [1,4,7] => '<1,4..^10>'; is_deeply [<1,5..^10>], [1,5,9] => '<1,5..^10>'; is_deeply [<1,6..^10>], [1,6] => '<1,6..^10>'; is_deeply [<1,7..^10>], [1,7] => '<1,7..^10>'; is_deeply [<1,8..^10>], [1,8] => '<1,8..^10>'; is_deeply [<1,9..^10>], [1,9] => '<1,9..^10>'; is_deeply [<1,10..^10>], [1] => '<1,10..^10>'; List-Maker-v0.0.5/t/unary_range.t0000644000076500007650000000322410451530642016073 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker; is_deeply [<^10>], [0,1,2,3,4,5,6,7,8,9] => '<^10>'; is_deeply [<^1>], [0] => '<^1>'; is_deeply [<^0>], [] => '<^0>'; is_deeply [<^-1>], [0] => '<^-1>'; is_deeply [<^-4>], [0,-1,-2,-3] => '<^-4>'; is_deeply [<^10 x 2>], [0,2,4,6,8] => '<^10 x 2>'; is_deeply [<^1 x 2>], [0] => '<^1 x 2>'; is_deeply [<^0 x 2>], [] => '<^0 x 2>'; is_deeply [<^-1 x -2>], [0] => '<^-1 x 2>'; is_deeply [<^-4 x -2>], [0,-2] => '<^-4 x 2>'; is_deeply [<^10 : X%2>], [1,3,5,7,9] => '<^10 : X%2>'; is_deeply [<^1 : X%2>], [] => '<^1 : X%2>'; is_deeply [<^0 : X%2>], [] => '<^0 : X%2>'; is_deeply [<^-1 : X%2>], [] => '<^-1 : X%2>'; is_deeply [<^-4 : X%2>], [-1,-3] => '<^-4 : X%2>'; is_deeply [<^10 x 2 : X%2>], [] => '<^10 x 2 : X%2>'; is_deeply [<^1 x 2 : X%2>], [] => '<^1 x 2 : X%2>'; is_deeply [<^0 x 2 : X%2>], [] => '<^0 x 2 : X%2>'; is_deeply [<^-1 x -2 : X%2>], [] => '<^-1 x 2 : X%2>'; is_deeply [<^-4 x -2 : X%2>], [] => '<^-4 x 2 : X%2>'; is_deeply [<^10 x 2 : not X%2>], [0,2,4,6,8] => '<^10 x 2 : X%2>'; is_deeply [<^1 x 2 : not X%2>], [0] => '<^1 x 2 : X%2>'; is_deeply [<^0 x 2 : not X%2>], [] => '<^0 x 2 : X%2>'; is_deeply [<^-1 x -2 : not X%2>], [0] => '<^-1 x 2 : X%2>'; is_deeply [<^-4 x -2 : not X%2>], [0,-2] => '<^-4 x 2 : X%2>'; List-Maker-v0.0.5/t/user_defined.t0000644000076500007650000000062010454620211016205 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker; my $count = 1; List::Maker::add_handler( qr/^ \s* (\d+) \s* d \s* (\d+) \s* $/xms => sub { ok $count==1 || $count==2 => "$1 d $2"; $count++; } ); List::Maker::add_handler( qr/^ \s* ' ( [^\\']*(?:\\.[^\\']*)* ) ' \s* x \s* (\d+) \s* $/xms => sub { is 3, $count => "xx"; } ); < 2d6 >; < 3 d 10 >; < 'cat' x 3 >; List-Maker-v0.0.5/t/wordlist.t0000644000076500007650000000174410451474671015446 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker; # LIST CONTEXT... is_deeply [< a word list >], ['a','word','list'] => '< a word list >'; is_deeply [< >], [] => '< >'; is_deeply [< "a word" list >], ['a word','list'] => '< "a word" list >'; is_deeply [< 'a word' list >], ['a word','list'] => '< \'a word\' list >'; is_deeply [< "o'word" list >], ['o\'word','list'] => '< "o\'word" list >'; is_deeply [< 'u"word' list >], ['u"word','list'] => '< \'u"word\' list >'; # SCALAR CONTEXT... is < a word list >."", 'a, word, and list' => '< a word list >'; is < "a word" list >."", 'a word and list' => '< "a word" list >'; is < 'a word' list >."", 'a word and list' => '< \'a word\' list >'; is < "o'word" list >."", 'o\'word and list' => '< "o\'word" list >'; is < 'u"word' list >."", 'u"word and list' => '< \'u"word\' list >'; is < word >."", 'word' => '< word >'; is < >."", '' => '< >'; List-Maker-v0.0.5/t/xx.t0000644000076500007650000000151610454622030014216 0ustar damiandamianuse Test::More 'no_plan'; use List::Maker; is_deeply [<'' xx 10>], [('') x 10] => q{<'' x 10>}; is_deeply [<'a' xx 10>], [('a') x 10] => q{<'a' x 10>}; is_deeply [<'aaa' xx 3>], [('aaa') x 3] => q{<'aaa' x 3>}; is_deeply [<'a"a' xx 3>], [('a"a') x 3] => q{<'a"a' x 3>}; is_deeply [<"" xx 10>], [("") x 10] => q{<"" x 10>}; is_deeply [<"a" xx 10>], [("a") x 10] => q{<"a" x 10>}; is_deeply [<"aaa" xx 3>], [("aaa") x 3] => q{<"aaa" x 3>}; is_deeply [<"a'a" xx 3>], [("a'a") x 3] => q{<"a'a" x 3>}; is_deeply [<0 xx 10>], [(0) x 10] => q{<0 x 10>}; is_deeply [<4 xx 10>], [(4) x 10] => q{<4 x 10>}; is_deeply [<42 xx 3>], [(42) x 3] => q{<42 x 3>}; is_deeply [<4.2 xx 3>], [(4.2) x 3] => q{<4.2 x 3>};