Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Removed all the syntactic sugar that Rakudo couldn't handle. Tired of…

… failing compilation
  • Loading branch information...
commit 31ac0526da73dc45a73f3beabad44a641299d25d 1 parent e15495c
@thundergnat authored
Showing with 75 additions and 163 deletions.
  1. +1 −1  META.info
  2. +59 −75 README
  3. +6 −23 lib/Sort/Naturally.pm6
  4. +9 −64 t/01-basic.t
View
2  META.info
@@ -1,6 +1,6 @@
{
"name" : "Sort::Naturally",
- "version" : "0.1.2",
+ "version" : "0.2.0",
"description" : "Provides several routines to ease natural sorting.",
"depends" : [],
"source-type" : "git",
View
134 README
@@ -4,19 +4,18 @@ Sort::Naturally
SYNOPSIS
+Provides a transform routine to modify sorting into a "natural" order.
+
- use v6;
use Sort::Naturally;
# sort strings containing a mix of letters and digits sensibly
my @a =
<1 11 100 14th 2 210 21 30 3rd d1 Any any d10 D2 D21 d3 aid Are ANY >;
- say ~@a.nsort;
- # or
- say @a.sort( { $^a ncmp $^b } ).join(' ');
+ say @a.sort: { .&naturally };
-@a.nsort yields:
+yeilds:
1 2 3rd 11 14th 21 30 100 141 210 aid ANY Any any Are d1 D2 d3 d10 D21
@@ -26,20 +25,17 @@ compared to @a.sort:
- # or sort a list of dotted quad notation IP addresses:
- my @ips = ((0..255).roll(4).join('.')for 0..99);
-
- .say for nsort @ips;
-
DESCRIPTION
-Similar though not identical to the Perl 5 Sort::Naturally. When sorting strings
-that contain groups of digits, will sort the groups of consecutive digits by
-"order of magnitude", then lexically by lower-cased terms. Order of magnitude is
-something of a simplification. Sort::Naturally doesn't try to interpret or
-evaluate a group of digits as a number, it just counts how many digits are in
-each group and uses that as its order of magnitude.
+This implementation of a natural sort order transform will yield results
+similar, though not identical to the Perl 5 Sort::Naturally. When sorting
+strings that contain groups of digits, it will sort the groups of consecutive
+digits by "order of magnitude", then lexically by lower-cased terms. Order of
+magnitude is something of a simplification. The transformation routine
+&naturally doesn't try to interpret or evaluate a group of digits as a number,
+it just counts how many digits are in each group and uses that as its order of
+magnitude.
The implications are:
@@ -63,94 +59,82 @@ However, that also means:
It is quite speedy. (For liberal values of speedy.) Since it doesn't need to
interpret numbers by value it eliminates a lot of code that would do that.
-Sort::Naturally could have been modified to ignore leading zeros, and in fact I
-experimented with that bit, but ran into issues with strings where leading zeros
-WERE significant. Just remember, it is for sorting strings, not numbers. It
-makes some attempt at treating groups of digits in a kind of numbery way, but
-they are still strings. If you truly want to sort numbers, use a numeric sort.
+It could have been modified to ignore leading zeros, and in fact I experimented
+with that bit, but ran into issues with strings where leading zeros WERE
+significant. Just remember, it is for sorting strings, not numbers. It makes
+some attempt at treating groups of digits in a kind of numbery way, but they are
+still strings. If you truly want to sort numbers, use a numeric sort.
USAGE
-Sort::Naturally has at its heart a sorting block modifier transformation
-routine: &naturally. This performs a transform of the sort terms so they will end
-up in the natural order.
+Sort::Naturally provides a transformation routine: &naturally, which you can use
+as a sorting block modifier. It performs a transform of the terms so they will
+end up in the natural order.
-C<nsort> is meant to be used as the primary natural sorting routine. Syntactic
-sugar for C<sort( { .&naturally } )>. May be called either as a method or a sub:
-C<@array.nsort> or C<nsort @array>.
+BACWARD COMPATIBILITY BREAKING CHANGES
-C<ncmp> is meant to be used in sort blocks. Syntactic sugar for C<sort( {
-$^a.naturally cmp $^b.naturally } )>. Useful when you need to do secondary
-sorts.
+Previous versions provided some pre-made augmented methods and infix comparators
+that are no longer provided. Partially because they were causing compilation
+failures due to incomplete and not yet implemented compiler features, and
+partially because I decided it was a bad idea to unnecessarily pollute the
+name-space. If you would like to have the syntactic sugar, it can be added
+easily.
-Say you have a hash containing the words in a document with the keys being the
-number of times each appears. You could sort by word frequency, then naturally
-as follows:
- ("%words{$_}, $_").say
- for sort {%words{$^b} <=> %words{$^a} || $^a ncmp $^b}, %words.keys;
+To create the method .nsort that can be used similar to .sort:
-Note: using a sort block with an arity > 1 will disable the default Schwartzian
-Transform and may be very slow. If that is an issue either do a manual
-Schwartzian Transform or some kind of caching of terms.
+use Sort::Naturally;
-nsort will flatten all parameters passed to it into lists whether called as a
-method or sub. (Previously, method calling conventions required manual
-flattening.) This means (@a1,@a2,@a3).nsort will return a list comprised of the
-contents of each of the arrays sorted in natural order, rather than a list of
-the three arrays nsorted on their names. This seems to more what would be
-expected following the Principle of least astonishment.
-http://en.wikipedia.org/wiki/Principle_of_least_astonishment
+use MONKEY_TYPING;
+augment class Any {
+ method nsort (*@) { self.list.flat.sort( { .&naturally } ) };
+}
+For a natural sorting infix comparator:
-BACKWARD COMPATIBILITY
+sub infix:<ncmp>($a, $b) { $a.&naturally cmp $b.&naturally }
+
+
+PERL 5 BACKWARD COMPATIBILITY
Perl 5 Sort::Naturally has an odd convention in that numbers at the beginning of
strings are sorted in ASCII order (digits sort before letters) but numbers
embedded inside strings are sorted in non-ASCII order (digits sort after
letters). While this is just plain strange in my opinion, some people may rely
-on or prefer this behavior so perl6 Sort::Naturally has "p5 compatibility mode"
-routines. These are analogues of the primary routines prepended with p5.
-
-C<p5naturally()>, C<p5nsort()> and C<p5ncmp>. Used identically to the p6
-versions.
+on or prefer this behavior so Perl 6 Sort::Naturally has a "p5 compatibility
+mode" routine. C<p5naturally()>.
for comparison:
- (' sort:',<foo12z foo foo13a fooa Foolio Foo12a foolio foo12 foo12a 9x 14>\
- .sort).join(' ').say;
- (' nsort:',<foo12z foo foo13a fooa Foolio Foo12a foolio foo12 foo12a 9x 14>\
- .nsort).join(' ').say;
- ('p5nsort:',<foo12z foo foo13a fooa Foolio Foo12a foolio foo12 foo12a 9x 14>\
- .p5nsort).join(' ').say;
+(' sort:',<foo12z foo foo13a fooa Foolio Foo12a foolio foo12 foo12a 9x 14>\
+ .sort).join(' ').say;
+(' naturally:',<foo12z foo foo13a fooa Foolio Foo12a foolio foo12 foo12a 9x 14>\
+ .sort({ .&naturally })).join(' ').say;
+('p5naturally:',<foo12z foo foo13a fooa Foolio Foo12a foolio foo12 foo12a 9x 14>\
+ .sort({ .&p5naturally })).join(' ').say;
yields:
- sort: 14 9x Foo12a Foolio foo foo12 foo12a foo12z foo13a fooa foolio
- nsort: 9x 14 foo foo12 Foo12a foo12a foo12z foo13a fooa Foolio foolio
- p5nsort: 9x 14 foo fooa Foolio foolio foo12 Foo12a foo12a foo12z foo13a
+ sort: 14 9x Foo12a Foolio foo foo12 foo12a foo12z foo13a fooa foolio
+ naturally: 9x 14 foo foo12 Foo12a foo12a foo12z foo13a fooa Foolio foolio
+ p5naturally: 9x 14 foo fooa Foolio foolio foo12 Foo12a foo12a foo12z foo13a
-By default, only the nsort routines are imported when you use Sort::Naturally.
-If you want to import the p5 compatibility routines instead, add the p5 tag.
-
-use Sort::Naturally :p5;
-
-This will load the p5 compatibility routines only. If you want both the standard
-and compatibility routines imported, use:
-
-use Sort::Naturally :ALL;
-
BUGS
-Tests and the p5* routines will fail under locales that specify lower case
-letters to sort before upper case. (EBCDIC locales notably). They will still
-sort consistently, just not in the order advertised. I can probably implement
-some kind of run time check to modify the behavior based on current locale.
-I'll look into it more seriously later if necessary.
+Tests and the p5 routine will fail under locales that specify lower case letters
+to sort before upper case. (EBCDIC locales notably). They will still sort
+consistently, just not in the order advertised. I can probably implement some
+kind of run time check to modify the behavior based on current locale. I'll look
+into it more seriously later if necessary. Right now, there are no Perl 6
+compilers for any EBDIC OSs so it is not really an issue yet.
+
+Right now, both normal and p5 compatabilty routine are always imported into the
+MAIN name-space when you use Sort::Naturally. When selective importing support
+gets a little better I'll revisit it.
View
29 lib/Sort/Naturally.pm6
@@ -1,30 +1,13 @@
-module Sort::Naturally:ver<0.1.2>;
+module Sort::Naturally:ver<0.2.0>;
use v6;
-use MONKEY_TYPING;
-augment class Any {
- method nsort (*@) { self.list.flat.sort( { .&naturally } ) };
- method p5nsort (*@) { self.list.flat.sort( { .&p5naturally } ) };
-}
-
-# Export the subroutines manually. Shouldn't be necessary but
-# module load order can affect class method exporting and make them unfindable.
-
-sub nsort(*@a) is export( :ALL, :DEFAULT ) { @a.list.flat.sort( { .&naturally } ) }
-sub p5nsort(*@a) is export( :ALL, :p5 ) { @a.list.flat.sort( { .&p5naturally } ) }
-
-# Sort modifier block routines
-
-sub infix:<ncmp>($a, $b) is export( :ALL, :DEFAULT ) { $a.&naturally cmp $b.&naturally }
-sub infix:<p5ncmp>($a, $b) is export( :ALL, :p5 ) { $a.&p5naturally cmp $b.&p5naturally }
-
-# Core routines to actually do the transformation for sorting
+# Routines to do the transformation for sorting
-sub naturally ($a) is export( :ALL, :DEFAULT ) {
- $a.lc.subst(/(\d+)/, ->$/ { "0{$0.gist.chars.chr}$0" }, :g) ~ "\x0$a"
+sub naturally ($a) is export {
+ $a.lc.subst(/(\d+)/, ->$/ { "0{$0.chars.chr}$0" }, :g) ~ "\x0$a"
}
-sub p5naturally ($a) is export( :ALL, :p5 ) {
+sub p5naturally ($a) is export {
$a.lc.subst(/^(\d+)/, -> $/ { "0{$0.gist.chars.chr}$0" } )\
- .subst(/<?after \D>(\d+)/, -> $/ { 'z{' ~"{$0.gist.chars.chr}$0" }, :g) ~ "\x0$a"
+ .subst(/<?after \D>(\d+)/, -> $/ { 'z{' ~"{$0.chars.chr}$0" }, :g) ~ "\x0$a"
}
View
73 t/01-basic.t
@@ -1,8 +1,8 @@
use v6;
use Test;
-use Sort::Naturally :ALL;
+use Sort::Naturally;
-plan 22;
+plan 5;
my @test;
my $nsorted = '';
@@ -11,29 +11,13 @@ my $nsorted = '';
is(~Nil.sort( { .&naturally } ), $nsorted,
"calling &naturally in a sort block on Nil is ok");
-is(~Nil.nsort, $nsorted,
- "calling nsort as method on Nil is ok");
-
-is(~nsort(Nil), $nsorted,
- "calling nsort as subroutine on Nil is ok");
-
-is(~Nil.sort( { $^a ncmp $^b } ), $nsorted, "calling ncmp in a sort block on Nil is ok");
-
-
# does it deal with empty array in a sane fashion?
is(~@test.sort( { .&naturally } ), $nsorted,
"calling &naturally in a sort block on an empty array is ok");
-
-is(~@test.nsort, $nsorted,
- "calling nsort as method on an empty array is ok");
-
-is(~nsort(@test), $nsorted,
- "calling nsort as subroutine on an empty array is ok");
-
-is(~@test.sort( { $^a ncmp $^b } ), $nsorted,
- "calling ncmp in a sort block on an empty array is ok");
+is(<5>.sort( { .&naturally } ), '5',
+ "calling &naturally in a single item is ok");
# does it return the terms in the expected order?
@test = <2 210 21 30 3rd d1 d10 D2 D21 d3 aid Are any ANY 1 Any 11 100 14th>;
@@ -42,56 +26,17 @@ $nsorted = '1 2 3rd 11 14th 21 30 100 210 aid ANY Any any Are d1 D2 d3 d10 D21';
# randomize list for each test
# could conceivably fail under some locales
-is(~@test.pick(+@test).sort( { .&naturally } ), $nsorted,
+is(~@test.pick(*).sort( { .&naturally } ), $nsorted,
"calling &naturally in a sort block yields expected order");
-
-is(~@test.pick(+@test).nsort, $nsorted,
- "calling nsort as method yields expected order");
-
-is(~nsort(@test.pick(+@test)), $nsorted,
- "calling nsort as subroutine yields expected order");
-
-is(~nsort(<2 210 21 30 3rd d1 d10 D2 D21 d3 aid Are
- any ANY 1 Any 11 100 14th>), $nsorted,
- "calling nsort as subroutine on a list gives expected order");
-
-is(~@test.pick(+@test).sort( { $^a ncmp $^b } ), $nsorted,
- "calling ncmp in a sort block yields expected order");
-
-is(~(@test[10..18],@test[0..9]).nsort, $nsorted,
- "nsort as method flattens its arguments and sorts as expected");
-
-is(~nsort(@test[10..18],@test[0..9]), $nsorted,
- "nsort as subroutine flattens its arguments and sorts as expected");
-
-# do the compatibility routines return terms in the expected order?
+# does the compatibility routine return terms in the expected order?
my @p5test = <foo12z foo foo13a fooa Foolio Foo12a foolio foo12 foo12a 9x 14>;
my $p5nsorted = '9x 14 foo fooa Foolio foolio foo12 Foo12a foo12a foo12z foo13a';
-# randomize list for each test
+# randomize list for the test
# could conceivably fail under some locales
-is(~@p5test.pick(+@p5test).sort( { .&p5naturally } ),
+is(~@p5test.pick(*).sort( { .&p5naturally } ),
$p5nsorted, "calling &p5naturally in a sort block yields expected order");
-is(~@p5test.pick(+@p5test).p5nsort, $p5nsorted,
- "calling p5nsort as method yields expected order");
-
-is(~p5nsort(@p5test.pick(+@p5test)), $p5nsorted,
- "calling p5nsort as subroutine yields expected order");
-
-is(~p5nsort(<foo12z foo foo13a fooa Foolio Foo12a
- foolio foo12 foo12a 9x 14>), $p5nsorted,
- "calling p5nsort as subroutine gives same order as method");
-
-is(~@p5test.pick(+@p5test).sort( { $^a p5ncmp $^b } ),
- $p5nsorted, "calling p5ncmp in a sort block yields expected order");
-
-is(~(@p5test[6..10],@p5test[0..5]).p5nsort, $p5nsorted,
- "p5nsort as method flattens its arguments and sorts as expected");
-
-is(~p5nsort(@p5test[6..10],@p5test[0..5]), $p5nsorted,
- "p5nsort as subroutine flattens its arguments and sorts as expected");
-
-
+done();
Please sign in to comment.
Something went wrong with that request. Please try again.