File Coverage

blib/lib/Lingua/EN/Number/Format/MixWithWords.pm
Criterion Covered Total %
statement 28 28 100.0
branch 4 6 66.6
condition 3 7 42.8
subroutine 8 8 100.0
pod 1 2 50.0
total 44 51 86.2


line stmt bran cond sub pod time code
1             package Lingua::EN::Number::Format::MixWithWords;
2              
3             our $DATE = '2016-06-14'; # DATE
4             our $VERSION = '0.08'; # VERSION
5              
6 2     2   575 use 5.010001;
  2         4  
7 2     2   6 use strict;
  2         0  
  2         27  
8 2     2   6 use warnings;
  2         2  
  2         37  
9              
10 2     2   713 use Lingua::Base::Number::Format::MixWithWords;
  2         2  
  2         55  
11 2     2   814 use parent qw(Lingua::Base::Number::Format::MixWithWords);
  2         416  
  2         8  
12              
13 2     2   97 use Exporter qw(import);
  2         2  
  2         623  
14             our @EXPORT_OK = qw(format_number_mix);
15              
16             our %SPEC;
17              
18             $SPEC{format_number_mix} = {
19             v => 1.1,
20             summary => 'Format number to a mixture of numbers and words (e.g. 12.3 million)',
21             args => {
22             num => {
23             summary => 'The input number to format',
24             schema => ['float*' => {}],
25             },
26             scale => {
27             summary => 'Pick long or short scale names',
28             description => <<_,
29             See http://en.wikipedia.org/wiki/Long_scale#Long_scale_countries_and_languages
30             for details.
31             _
32             schema => ['str*' => {
33             in => ['short', 'long'],
34             }],
35             },
36             num_decimal => {
37             summary => 'Number of decimal points to round',
38             description => <<'_',
39             Can be negative, e.g. -1 to round to nearest 10, -2 to nearest 100, and so on.
40             _
41             schema => ['int' => {
42             }],
43             },
44             min_format => {
45             summary => 'Number must be larger than this to be formatted as '.
46             'mixture of number and word',
47             schema => ['float*' => {
48             }],
49             default => 1000000,
50             },
51             min_fraction => {
52             summary => 'Whether smaller number can be formatted with 0,x',
53             description => <<_,
54             If min_fraction is 1 (the default) or 0.9, 800000 won't be formatted as 0.9
55             omillion but will be if min_fraction is 0.8.
56             _
57             schema => ['float*' => {
58             min => 0,
59             max => 1,
60             }],
61             default => 1,
62             },
63             },
64             result_naked => 1,
65             };
66             sub format_number_mix {
67 18     18 1 21332 my %args = @_;
68              
69             my $f = __PACKAGE__->new(
70             num_decimal => $args{num_decimal},
71             min_format => $args{min_format},
72             min_fraction => $args{min_fraction},
73             scale => $args{scale},
74 18         110 );
75 18         71 $f->_format($args{num});
76             }
77              
78             my $en_short_names = {
79             #2 => 'hundred',
80             3 => 'thousand',
81             6 => 'million',
82             9 => 'billion',
83             12 => 'trillion',
84             15 => 'quadrillion',
85             18 => 'quintillion',
86             21 => 'sextillion',
87             24 => 'septillion',
88             27 => 'octillion',
89             30 => 'nonillion',
90             33 => 'decillion',
91             36 => 'undecillion',
92             39 => 'duodecillion',
93             42 => 'tredecillion',
94             45 => 'quattuordecillion',
95             48 => 'quindecillion',
96             51 => 'sexdecillion',
97             54 => 'septendecillion',
98             57 => 'octodecillion',
99             60 => 'novemdecillion',
100             63 => 'vigintillion',
101             100 => 'googol',
102             303 => 'centillion',
103             };
104              
105             my $en_long_names = {
106             #2 => 'hundred',
107             3 => 'thousand',
108             6 => 'million',
109             12 => 'billion',
110             15 => 'billiard',
111             18 => 'trillion',
112             24 => 'quadrillion',
113             30 => 'quintillion',
114             36 => 'sextillion',
115             42 => 'septillion',
116             48 => 'octillion',
117             54 => 'nonillion',
118             60 => 'decillion',
119             66 => 'undecillion',
120             72 => 'duodecillion',
121             78 => 'tredecillion',
122             84 => 'quattuordecillion',
123             90 => 'quindecillion',
124             96 => 'sexdecillion',
125             102 => 'septendecillion',
126             108 => 'octodecillion',
127             114 => 'novemdecillion',
128             120 => 'vigintillion',
129             100 => 'googol',
130             600 => 'centillion',
131             };
132              
133             sub new {
134 18     18 0 62 my ($class, %args) = @_;
135 18   50     78 $args{decimal_point} //= ".";
136 18   50     48 $args{thousands_sep} //= ",";
137 18 50       34 die "Please specify scale" unless $args{scale};
138             die "Invalid scale, please use short/long"
139 18 50       78 unless $args{scale} =~ /\A(short|long)\z/;
140 18 100 33     77 $args{names} //= ($args{scale} eq 'long' ? $en_long_names:$en_short_names);
141             # XXX should use "SUPER"
142 18         76 my $self = Lingua::Base::Number::Format::MixWithWords->new(%args);
143 18         48 bless $self, $class;
144             }
145              
146             1;
147             # ABSTRACT: Format number to a mixture of numbers and words (e.g. 12.3 million)
148              
149             __END__