File Coverage

blib/lib/Lingua/EN/Numbers/Ordinate.pm
Criterion Covered Total %
statement 22 22 100.0
branch 10 10 100.0
condition 11 11 100.0
subroutine 6 6 100.0
pod 2 2 100.0
total 51 51 100.0


line stmt bran cond sub pod time code
1             package Lingua::EN::Numbers::Ordinate;
2             $Lingua::EN::Numbers::Ordinate::VERSION = '1.04_01'; # TRIAL
3              
4             $Lingua::EN::Numbers::Ordinate::VERSION = '1.0401';# ABSTRACT: go from cardinal number (3) to ordinal ("3rd")
5              
6 2     2   139950 use 5.006;
  2         15  
7 2     2   11 use strict;
  2         4  
  2         61  
8 2     2   11 use warnings;
  2         4  
  2         568  
9             require Exporter;
10              
11             our @ISA = qw/ Exporter /;
12             our @EXPORT = qw/ ordinate /;
13             our @EXPORT_OK = qw/ ordsuf th /;
14              
15             ###########################################################################
16              
17             =head1 NAME
18              
19             Lingua::EN::Numbers::Ordinate -- go from cardinal number (3) to ordinal ("3rd")
20              
21             =head1 SYNOPSIS
22              
23             use Lingua::EN::Numbers::Ordinate;
24             print ordinate(4), "\n";
25             # prints 4th
26             print ordinate(-342), "\n";
27             # prints -342nd
28              
29             # Example of actual use:
30             ...
31             for(my $i = 0; $i < @records; $i++) {
32             unless(is_valid($record[$i]) {
33             warn "The ", ordinate($i), " record is invalid!\n";
34             next;
35             }
36             ...
37             }
38              
39             =head1 DESCRIPTION
40              
41             There are two kinds of numbers in English -- cardinals (1, 2, 3...), and
42             ordinals (1st, 2nd, 3rd...). This library provides functions for giving
43             the ordinal form of a number, given its cardinal value.
44              
45             =head1 FUNCTIONS
46              
47             =over
48              
49             =item ordinate(SCALAR)
50              
51             Returns a string consisting of that scalar's string form, plus the
52             appropriate ordinal suffix. Example: C returns "23rd".
53              
54             As a special case, C and C return "0th",
55             not "th".
56              
57             This function is exported by default.
58              
59             =item th(SCALAR)
60              
61             Merely an alias for C, but not exported by default.
62              
63             =item ordsuf(SCALAR)
64              
65             Returns just the appropriate ordinal suffix for the given scalar
66             numeric value. This is what C uses to actually do its
67             work. For example, C is "rd".
68              
69             Not exported by default.
70              
71             =back
72              
73             The above functions are all prototyped to take a scalar value,
74             so C is the same as C.
75              
76             =head1 CAVEATS
77              
78             * Note that this library knows only about numbers, not number-words.
79             C might just as well be C
80             or C -- you'll get the fallthru case of the input
81             string plus "th".
82              
83             * As is unavoidable, C returns "174th" (because ordinate
84             sees the value 174). Similarly, C returns
85             "1000000000000th". Returning "trillionth" would be nice, but that's an
86             awfully atypical case.
87              
88             * Note that this library's algorithm (as well as the basic concept
89             and implementation of ordinal numbers) is totally language specific.
90              
91             To pick a trivial example, consider that in French, 1 ordinates
92             as "1ier", whereas 41 ordinates as "41ieme".
93              
94             =head1 STILL NOT SATISFIED?
95              
96             Bored of this...?
97              
98             use Lingua::EN::Numbers::Ordinate qw(ordinate th);
99             ...
100             print th($n), " entry processed...\n";
101             ...
102              
103             Try this bit of lunacy:
104              
105             {
106             my $th_object;
107             sub _th () { $th_object }
108              
109             package Lingua::EN::Numbers::Ordinate::Overloader;
110             my $x; # Gotta have something to bless.
111             $th_object = bless \$x; # Define the object now, which _th returns
112             use Carp ();
113             use Lingua::EN::Numbers::Ordinate ();
114             sub overordinate {
115             Carp::croak "_th should be used only as postfix!" unless $_[2];
116             Lingua::EN::Numbers::Ordinate::ordinate($_[1]);
117             }
118             use overload '&' => \&overordinate;
119             }
120              
121             Then you get to do:
122              
123             print 3 & _th, "\n";
124             # prints "3rd"
125            
126             print 1 + 2 & _th, "\n";
127             # prints "3rd" too!
128             # Because of the precedence of & !
129            
130             print _th & 3, "\n";
131             # dies with: "th should be used only as postfix!"
132              
133             Kooky, isn't it? For more delightful deleria like this, see
134             Damian Conway's I from Manning Press.
135              
136             Kinda makes you like C, doesn't it?
137              
138             =head1 SEE ALSO
139              
140             L provides an C function,
141             which returns the ordinal form of a cardinal number.
142              
143             L provides an C
144             function, which returns true if passed an ordinal number.
145              
146             =head1 REPOSITORY
147              
148             L
149              
150             =head1 COPYRIGHT
151              
152             Copyright (c) 2000 Sean M. Burke. All rights reserved.
153              
154             This library is free software; you can redistribute it and/or
155             modify it under the same terms as Perl itself.
156              
157             =head1 AUTHOR
158              
159             Sean M. Burke C
160              
161             =cut
162              
163             ###########################################################################
164              
165             sub ordsuf ($) {
166 48 100 100 48 1 8557 return 'th' if not(defined($_[0])) or $_[0] !~ /^-?[0-9]+$/;
167             # 'th' for undef, 0, or anything non-number.
168 43         86 my $n = abs($_[0]); # Throw away the sign.
169              
170 43         79 $n %= 100;
171 43 100 100     208 return 'th' if $n == 11 or $n == 12 or $n == 13;
      100        
172 31         40 $n %= 10;
173 31 100       68 return 'st' if $n == 1;
174 28 100       65 return 'nd' if $n == 2;
175 22 100       59 return 'rd' if $n == 3;
176 13         38 return 'th';
177             }
178              
179             sub ordinate ($) {
180 32   100 32 1 16994 my $i = $_[0] || 0;
181 32         68 return $i . ordsuf($i);
182             }
183              
184 2     2   17 no warnings 'all';
  2         4  
  2         145  
185             *th = \&ordinate; # correctly copies the prototype, too.
186              
187             ###########################################################################
188             1;
189              
190             __END__