core_ext 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 65bef674a3f30a7d453c6daf9c001da0ad8ce670
4
- data.tar.gz: 4091487a2288aeeb53d9a65f16b64bd91e71962a
3
+ metadata.gz: 1bdf3f20c2a4605b931d22569286e4d4a2bc5b89
4
+ data.tar.gz: c27a153f427d418addb719755493eab242b85d95
5
5
  SHA512:
6
- metadata.gz: c4eedaeea00537d6013ce8a4e4176b219bc20894776a27241c6781c611382f92753923d75604ca6d2d7bcb6748dce6d2580993aeceb763b209601d4e846bd95e
7
- data.tar.gz: 8c7e8c31d381fcfa7511f98a5764fed0fe449bfc1b524cd3968c3766ff05f59751d5686b51f016ff79f76f9475fc56b10f9a12bcf4fd8e98c15c97e430854aad
6
+ metadata.gz: fe9e06e452543c0d39defe62ca3117d022987aedb45c7ee2c373a14a59413c20fa30104b31ad3c528e8c3b1056bccda89624c5bddf686dadd9ea45879bd919ab
7
+ data.tar.gz: f2f93d74095ddb305b276d5027fb18fd52361cff76ff1f806a66ecb78f990137be868aaa8e9625f6bb6f2e7535bd62090eaea17a31bc3f654827a53fae42126f
data/lib/core_ext.rb CHANGED
@@ -1,4 +1,7 @@
1
+ require "core_ext/version"
2
+ require "core_ext/module/attribute_accessors"
3
+
1
4
  module CoreExt
5
+ cattr_accessor :test_order # :nodoc :
2
6
  end
3
7
 
4
- require "core_ext/version"
@@ -1,4 +1,5 @@
1
1
  require 'core_ext/concern'
2
+ require 'core_ext/descendants_tracker'
2
3
  require 'core_ext/array/extract_options'
3
4
  require 'core_ext/class/attribute'
4
5
  require 'core_ext/kernel/reporting'
@@ -60,6 +61,10 @@ module CoreExt
60
61
  module Callbacks
61
62
  extend Concern
62
63
 
64
+ included do
65
+ extend CoreExt::DescendantsTracker
66
+ end
67
+
63
68
  CALLBACK_FILTER_TYPES = [:before, :after, :around]
64
69
 
65
70
  # If true, Active Record and Active Model callbacks returning +false+ will
@@ -551,8 +556,10 @@ module CoreExt
551
556
  # This is used internally to append, prepend and skip callbacks to the
552
557
  # CallbackChain.
553
558
  def __update_callbacks(name) #:nodoc:
554
- chain = get_callbacks name
555
- yield self, chain.dup
559
+ ([self] + CoreExt::DescendantsTracker.descendants(self)).reverse_each do |target|
560
+ chain = target.get_callbacks name
561
+ yield target, chain.dup
562
+ end
556
563
  end
557
564
 
558
565
  # Install a callback for the given event.
@@ -641,6 +648,12 @@ module CoreExt
641
648
  # Remove all set callbacks for the given event.
642
649
  def reset_callbacks(name)
643
650
  callbacks = get_callbacks name
651
+ CoreExt::DescendantsTracker.descendants(self).each do |target|
652
+ chain = target.get_callbacks(name).dup
653
+ callbacks.each { |c| chain.delete(c) }
654
+ target.set_callbacks name, chain
655
+ end
656
+
644
657
  set_callbacks name, callbacks.dup.clear
645
658
  end
646
659
 
@@ -0,0 +1,50 @@
1
+ module CoreExt
2
+ # This module provides an internal implementation to track descendants
3
+ # which is faster than iterating through ObjectSpace.
4
+ module DescendantsTracker
5
+ @@direct_descendants = {}
6
+
7
+ class << self
8
+ def direct_descendants(klass)
9
+ @@direct_descendants[klass] || []
10
+ end
11
+
12
+ def descendants(klass)
13
+ arr = []
14
+ accumulate_descendants(klass, arr)
15
+ arr
16
+ end
17
+
18
+ def clear
19
+ @@direct_descendants.clear
20
+ end
21
+
22
+ # This is the only method that is not thread safe, but is only ever called
23
+ # during the eager loading phase.
24
+ def store_inherited(klass, descendant)
25
+ (@@direct_descendants[klass] ||= []) << descendant
26
+ end
27
+
28
+ private
29
+ def accumulate_descendants(klass, acc)
30
+ if direct_descendants = @@direct_descendants[klass]
31
+ acc.concat(direct_descendants)
32
+ direct_descendants.each { |direct_descendant| accumulate_descendants(direct_descendant, acc) }
33
+ end
34
+ end
35
+ end
36
+
37
+ def inherited(base)
38
+ DescendantsTracker.store_inherited(self, base)
39
+ super
40
+ end
41
+
42
+ def direct_descendants
43
+ DescendantsTracker.direct_descendants(self)
44
+ end
45
+
46
+ def descendants
47
+ DescendantsTracker.descendants(self)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,36 @@
1
+ require 'zlib'
2
+ require 'stringio'
3
+
4
+ module CoreExt
5
+ # A convenient wrapper for the zlib standard library that allows
6
+ # compression/decompression of strings with gzip.
7
+ #
8
+ # gzip = CoreExt::Gzip.compress('compress me!')
9
+ # # => "\x1F\x8B\b\x00o\x8D\xCDO\x00\x03K\xCE\xCF-(J-.V\xC8MU\x04\x00R>n\x83\f\x00\x00\x00"
10
+ #
11
+ # CoreExt::Gzip.decompress(gzip)
12
+ # # => "compress me!"
13
+ module Gzip
14
+ class Stream < StringIO
15
+ def initialize(*)
16
+ super
17
+ set_encoding "BINARY"
18
+ end
19
+ def close; rewind; end
20
+ end
21
+
22
+ # Decompresses a gzipped string.
23
+ def self.decompress(source)
24
+ Zlib::GzipReader.new(StringIO.new(source)).read
25
+ end
26
+
27
+ # Compresses a string using gzip.
28
+ def self.compress(source, level=Zlib::DEFAULT_COMPRESSION, strategy=Zlib::DEFAULT_STRATEGY)
29
+ output = Stream.new
30
+ gz = Zlib::GzipWriter.new(output, level, strategy)
31
+ gz.write(source)
32
+ gz.close
33
+ output.string
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,11 @@
1
+ require 'core_ext/hash/deep_merge'
2
+ require 'core_ext/hash/except'
3
+ require 'core_ext/hash/slice'
4
+ begin
5
+ require 'i18n'
6
+ rescue LoadError => e
7
+ $stderr.puts "The i18n gem is not available. Please add it to your Gemfile and run bundle install"
8
+ raise e
9
+ end
10
+
11
+ I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
@@ -0,0 +1,135 @@
1
+ en:
2
+ date:
3
+ formats:
4
+ # Use the strftime parameters for formats.
5
+ # When no format has been given, it uses default.
6
+ # You can provide other formats here if you like!
7
+ default: "%Y-%m-%d"
8
+ short: "%b %d"
9
+ long: "%B %d, %Y"
10
+
11
+ day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
12
+ abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
13
+
14
+ # Don't forget the nil at the beginning; there's no such thing as a 0th month
15
+ month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
16
+ abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
17
+ # Used in date_select and datetime_select.
18
+ order:
19
+ - year
20
+ - month
21
+ - day
22
+
23
+ time:
24
+ formats:
25
+ default: "%a, %d %b %Y %H:%M:%S %z"
26
+ short: "%d %b %H:%M"
27
+ long: "%B %d, %Y %H:%M"
28
+ am: "am"
29
+ pm: "pm"
30
+
31
+ # Used in array.to_sentence.
32
+ support:
33
+ array:
34
+ words_connector: ", "
35
+ two_words_connector: " and "
36
+ last_word_connector: ", and "
37
+ number:
38
+ # Used in NumberHelper.number_to_delimited()
39
+ # These are also the defaults for 'currency', 'percentage', 'precision', and 'human'
40
+ format:
41
+ # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5)
42
+ separator: "."
43
+ # Delimits thousands (e.g. 1,000,000 is a million) (always in groups of three)
44
+ delimiter: ","
45
+ # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00)
46
+ precision: 3
47
+ # If set to true, precision will mean the number of significant digits instead
48
+ # of the number of decimal digits (1234 with precision 2 becomes 1200, 1.23543 becomes 1.2)
49
+ significant: false
50
+ # If set, the zeros after the decimal separator will always be stripped (eg.: 1.200 will be 1.2)
51
+ strip_insignificant_zeros: false
52
+
53
+ # Used in NumberHelper.number_to_currency()
54
+ currency:
55
+ format:
56
+ # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00)
57
+ format: "%u%n"
58
+ unit: "$"
59
+ # These five are to override number.format and are optional
60
+ separator: "."
61
+ delimiter: ","
62
+ precision: 2
63
+ significant: false
64
+ strip_insignificant_zeros: false
65
+
66
+ # Used in NumberHelper.number_to_percentage()
67
+ percentage:
68
+ format:
69
+ # These five are to override number.format and are optional
70
+ # separator:
71
+ delimiter: ""
72
+ # precision:
73
+ # significant: false
74
+ # strip_insignificant_zeros: false
75
+ format: "%n%"
76
+
77
+ # Used in NumberHelper.number_to_rounded()
78
+ precision:
79
+ format:
80
+ # These five are to override number.format and are optional
81
+ # separator:
82
+ delimiter: ""
83
+ # precision:
84
+ # significant: false
85
+ # strip_insignificant_zeros: false
86
+
87
+ # Used in NumberHelper.number_to_human_size() and NumberHelper.number_to_human()
88
+ human:
89
+ format:
90
+ # These five are to override number.format and are optional
91
+ # separator:
92
+ delimiter: ""
93
+ precision: 3
94
+ significant: true
95
+ strip_insignificant_zeros: true
96
+ # Used in number_to_human_size()
97
+ storage_units:
98
+ # Storage units output formatting.
99
+ # %u is the storage unit, %n is the number (default: 2 MB)
100
+ format: "%n %u"
101
+ units:
102
+ byte:
103
+ one: "Byte"
104
+ other: "Bytes"
105
+ kb: "KB"
106
+ mb: "MB"
107
+ gb: "GB"
108
+ tb: "TB"
109
+ pb: "PB"
110
+ eb: "EB"
111
+ # Used in NumberHelper.number_to_human()
112
+ decimal_units:
113
+ format: "%n %u"
114
+ # Decimal units output formatting
115
+ # By default we will only quantify some of the exponents
116
+ # but the commented ones might be defined or overridden
117
+ # by the user.
118
+ units:
119
+ # femto: Quadrillionth
120
+ # pico: Trillionth
121
+ # nano: Billionth
122
+ # micro: Millionth
123
+ # mili: Thousandth
124
+ # centi: Hundredth
125
+ # deci: Tenth
126
+ unit: ""
127
+ # ten:
128
+ # one: Ten
129
+ # other: Tens
130
+ # hundred: Hundred
131
+ thousand: Thousand
132
+ million: Million
133
+ billion: Billion
134
+ trillion: Trillion
135
+ quadrillion: Quadrillion
@@ -0,0 +1,358 @@
1
+ module CoreExt
2
+ module NumberHelper
3
+
4
+ require "core_ext/number_helper/number_converter"
5
+ require "core_ext/number_helper/number_to_rounded_converter"
6
+ require "core_ext/number_helper/number_to_delimited_converter"
7
+ require "core_ext/number_helper/number_to_human_converter"
8
+ require "core_ext/number_helper/number_to_human_size_converter"
9
+ require "core_ext/number_helper/number_to_phone_converter"
10
+ require "core_ext/number_helper/number_to_currency_converter"
11
+ require "core_ext/number_helper/number_to_percentage_converter"
12
+
13
+ extend self
14
+
15
+ # Formats a +number+ into a US phone number (e.g., (555)
16
+ # 123-9876). You can customize the format in the +options+ hash.
17
+ #
18
+ # ==== Options
19
+ #
20
+ # * <tt>:area_code</tt> - Adds parentheses around the area code.
21
+ # * <tt>:delimiter</tt> - Specifies the delimiter to use
22
+ # (defaults to "-").
23
+ # * <tt>:extension</tt> - Specifies an extension to add to the
24
+ # end of the generated number.
25
+ # * <tt>:country_code</tt> - Sets the country code for the phone
26
+ # number.
27
+ # ==== Examples
28
+ #
29
+ # number_to_phone(5551234) # => 555-1234
30
+ # number_to_phone('5551234') # => 555-1234
31
+ # number_to_phone(1235551234) # => 123-555-1234
32
+ # number_to_phone(1235551234, area_code: true) # => (123) 555-1234
33
+ # number_to_phone(1235551234, delimiter: ' ') # => 123 555 1234
34
+ # number_to_phone(1235551234, area_code: true, extension: 555) # => (123) 555-1234 x 555
35
+ # number_to_phone(1235551234, country_code: 1) # => +1-123-555-1234
36
+ # number_to_phone('123a456') # => 123a456
37
+ #
38
+ # number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: '.')
39
+ # # => +1.123.555.1234 x 1343
40
+ def number_to_phone(number, options = {})
41
+ NumberToPhoneConverter.convert(number, options)
42
+ end
43
+
44
+ # Formats a +number+ into a currency string (e.g., $13.65). You
45
+ # can customize the format in the +options+ hash.
46
+ #
47
+ # The currency unit and number formatting of the current locale will be used
48
+ # unless otherwise specified in the provided options. No currency conversion
49
+ # is performed. If the user is given a way to change their locale, they will
50
+ # also be able to change the relative value of the currency displayed with
51
+ # this helper. If your application will ever support multiple locales, you
52
+ # may want to specify a constant <tt>:locale</tt> option or consider
53
+ # using a library capable of currency conversion.
54
+ #
55
+ # ==== Options
56
+ #
57
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
58
+ # (defaults to current locale).
59
+ # * <tt>:precision</tt> - Sets the level of precision (defaults
60
+ # to 2).
61
+ # * <tt>:unit</tt> - Sets the denomination of the currency
62
+ # (defaults to "$").
63
+ # * <tt>:separator</tt> - Sets the separator between the units
64
+ # (defaults to ".").
65
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
66
+ # to ",").
67
+ # * <tt>:format</tt> - Sets the format for non-negative numbers
68
+ # (defaults to "%u%n"). Fields are <tt>%u</tt> for the
69
+ # currency, and <tt>%n</tt> for the number.
70
+ # * <tt>:negative_format</tt> - Sets the format for negative
71
+ # numbers (defaults to prepending an hyphen to the formatted
72
+ # number given by <tt>:format</tt>). Accepts the same fields
73
+ # than <tt>:format</tt>, except <tt>%n</tt> is here the
74
+ # absolute value of the number.
75
+ #
76
+ # ==== Examples
77
+ #
78
+ # number_to_currency(1234567890.50) # => $1,234,567,890.50
79
+ # number_to_currency(1234567890.506) # => $1,234,567,890.51
80
+ # number_to_currency(1234567890.506, precision: 3) # => $1,234,567,890.506
81
+ # number_to_currency(1234567890.506, locale: :fr) # => 1 234 567 890,51 €
82
+ # number_to_currency('123a456') # => $123a456
83
+ #
84
+ # number_to_currency(-1234567890.50, negative_format: '(%u%n)')
85
+ # # => ($1,234,567,890.50)
86
+ # number_to_currency(1234567890.50, unit: '&pound;', separator: ',', delimiter: '')
87
+ # # => &pound;1234567890,50
88
+ # number_to_currency(1234567890.50, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
89
+ # # => 1234567890,50 &pound;
90
+ def number_to_currency(number, options = {})
91
+ NumberToCurrencyConverter.convert(number, options)
92
+ end
93
+
94
+ # Formats a +number+ as a percentage string (e.g., 65%). You can
95
+ # customize the format in the +options+ hash.
96
+ #
97
+ # ==== Options
98
+ #
99
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
100
+ # (defaults to current locale).
101
+ # * <tt>:precision</tt> - Sets the precision of the number
102
+ # (defaults to 3). Keeps the number's precision if nil.
103
+ # * <tt>:significant</tt> - If +true+, precision will be the number
104
+ # of significant_digits. If +false+, the number of fractional
105
+ # digits (defaults to +false+).
106
+ # * <tt>:separator</tt> - Sets the separator between the
107
+ # fractional and integer digits (defaults to ".").
108
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
109
+ # to "").
110
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
111
+ # insignificant zeros after the decimal separator (defaults to
112
+ # +false+).
113
+ # * <tt>:format</tt> - Specifies the format of the percentage
114
+ # string The number field is <tt>%n</tt> (defaults to "%n%").
115
+ #
116
+ # ==== Examples
117
+ #
118
+ # number_to_percentage(100) # => 100.000%
119
+ # number_to_percentage('98') # => 98.000%
120
+ # number_to_percentage(100, precision: 0) # => 100%
121
+ # number_to_percentage(1000, delimiter: '.', separator: ',') # => 1.000,000%
122
+ # number_to_percentage(302.24398923423, precision: 5) # => 302.24399%
123
+ # number_to_percentage(1000, locale: :fr) # => 1000,000%
124
+ # number_to_percentage(1000, precision: nil) # => 1000%
125
+ # number_to_percentage('98a') # => 98a%
126
+ # number_to_percentage(100, format: '%n %') # => 100.000 %
127
+ def number_to_percentage(number, options = {})
128
+ NumberToPercentageConverter.convert(number, options)
129
+ end
130
+
131
+ # Formats a +number+ with grouped thousands using +delimiter+
132
+ # (e.g., 12,324). You can customize the format in the +options+
133
+ # hash.
134
+ #
135
+ # ==== Options
136
+ #
137
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
138
+ # (defaults to current locale).
139
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
140
+ # to ",").
141
+ # * <tt>:separator</tt> - Sets the separator between the
142
+ # fractional and integer digits (defaults to ".").
143
+ # * <tt>:delimiter_pattern</tt> - Sets a custom regular expression used for
144
+ # deriving the placement of delimiter. Helpful when using currency formats
145
+ # like INR.
146
+ #
147
+ # ==== Examples
148
+ #
149
+ # number_to_delimited(12345678) # => 12,345,678
150
+ # number_to_delimited('123456') # => 123,456
151
+ # number_to_delimited(12345678.05) # => 12,345,678.05
152
+ # number_to_delimited(12345678, delimiter: '.') # => 12.345.678
153
+ # number_to_delimited(12345678, delimiter: ',') # => 12,345,678
154
+ # number_to_delimited(12345678.05, separator: ' ') # => 12,345,678 05
155
+ # number_to_delimited(12345678.05, locale: :fr) # => 12 345 678,05
156
+ # number_to_delimited('112a') # => 112a
157
+ # number_to_delimited(98765432.98, delimiter: ' ', separator: ',')
158
+ # # => 98 765 432,98
159
+ # number_to_delimited("123456.78",
160
+ # delimiter_pattern: /(\d+?)(?=(\d\d)+(\d)(?!\d))/)
161
+ # # => 1,23,456.78
162
+ def number_to_delimited(number, options = {})
163
+ NumberToDelimitedConverter.convert(number, options)
164
+ end
165
+
166
+ # Formats a +number+ with the specified level of
167
+ # <tt>:precision</tt> (e.g., 112.32 has a precision of 2 if
168
+ # +:significant+ is +false+, and 5 if +:significant+ is +true+).
169
+ # You can customize the format in the +options+ hash.
170
+ #
171
+ # ==== Options
172
+ #
173
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
174
+ # (defaults to current locale).
175
+ # * <tt>:precision</tt> - Sets the precision of the number
176
+ # (defaults to 3). Keeps the number's precision if nil.
177
+ # * <tt>:significant</tt> - If +true+, precision will be the number
178
+ # of significant_digits. If +false+, the number of fractional
179
+ # digits (defaults to +false+).
180
+ # * <tt>:separator</tt> - Sets the separator between the
181
+ # fractional and integer digits (defaults to ".").
182
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
183
+ # to "").
184
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
185
+ # insignificant zeros after the decimal separator (defaults to
186
+ # +false+).
187
+ #
188
+ # ==== Examples
189
+ #
190
+ # number_to_rounded(111.2345) # => 111.235
191
+ # number_to_rounded(111.2345, precision: 2) # => 111.23
192
+ # number_to_rounded(13, precision: 5) # => 13.00000
193
+ # number_to_rounded(389.32314, precision: 0) # => 389
194
+ # number_to_rounded(111.2345, significant: true) # => 111
195
+ # number_to_rounded(111.2345, precision: 1, significant: true) # => 100
196
+ # number_to_rounded(13, precision: 5, significant: true) # => 13.000
197
+ # number_to_rounded(13, precision: nil) # => 13
198
+ # number_to_rounded(111.234, locale: :fr) # => 111,234
199
+ #
200
+ # number_to_rounded(13, precision: 5, significant: true, strip_insignificant_zeros: true)
201
+ # # => 13
202
+ #
203
+ # number_to_rounded(389.32314, precision: 4, significant: true) # => 389.3
204
+ # number_to_rounded(1111.2345, precision: 2, separator: ',', delimiter: '.')
205
+ # # => 1.111,23
206
+ def number_to_rounded(number, options = {})
207
+ NumberToRoundedConverter.convert(number, options)
208
+ end
209
+
210
+ # Formats the bytes in +number+ into a more understandable
211
+ # representation (e.g., giving it 1500 yields 1.5 KB). This
212
+ # method is useful for reporting file sizes to users. You can
213
+ # customize the format in the +options+ hash.
214
+ #
215
+ # See <tt>number_to_human</tt> if you want to pretty-print a
216
+ # generic number.
217
+ #
218
+ # ==== Options
219
+ #
220
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
221
+ # (defaults to current locale).
222
+ # * <tt>:precision</tt> - Sets the precision of the number
223
+ # (defaults to 3).
224
+ # * <tt>:significant</tt> - If +true+, precision will be the number
225
+ # of significant_digits. If +false+, the number of fractional
226
+ # digits (defaults to +true+)
227
+ # * <tt>:separator</tt> - Sets the separator between the
228
+ # fractional and integer digits (defaults to ".").
229
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
230
+ # to "").
231
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
232
+ # insignificant zeros after the decimal separator (defaults to
233
+ # +true+)
234
+ #
235
+ # ==== Examples
236
+ #
237
+ # number_to_human_size(123) # => 123 Bytes
238
+ # number_to_human_size(1234) # => 1.21 KB
239
+ # number_to_human_size(12345) # => 12.1 KB
240
+ # number_to_human_size(1234567) # => 1.18 MB
241
+ # number_to_human_size(1234567890) # => 1.15 GB
242
+ # number_to_human_size(1234567890123) # => 1.12 TB
243
+ # number_to_human_size(1234567890123456) # => 1.1 PB
244
+ # number_to_human_size(1234567890123456789) # => 1.07 EB
245
+ # number_to_human_size(1234567, precision: 2) # => 1.2 MB
246
+ # number_to_human_size(483989, precision: 2) # => 470 KB
247
+ # number_to_human_size(1234567, precision: 2, separator: ',') # => 1,2 MB
248
+ # number_to_human_size(1234567890123, precision: 5) # => "1.1228 TB"
249
+ # number_to_human_size(524288000, precision: 5) # => "500 MB"
250
+ def number_to_human_size(number, options = {})
251
+ NumberToHumanSizeConverter.convert(number, options)
252
+ end
253
+
254
+ # Pretty prints (formats and approximates) a number in a way it
255
+ # is more readable by humans (eg.: 1200000000 becomes "1.2
256
+ # Billion"). This is useful for numbers that can get very large
257
+ # (and too hard to read).
258
+ #
259
+ # See <tt>number_to_human_size</tt> if you want to print a file
260
+ # size.
261
+ #
262
+ # You can also define your own unit-quantifier names if you want
263
+ # to use other decimal units (eg.: 1500 becomes "1.5
264
+ # kilometers", 0.150 becomes "150 milliliters", etc). You may
265
+ # define a wide range of unit quantifiers, even fractional ones
266
+ # (centi, deci, mili, etc).
267
+ #
268
+ # ==== Options
269
+ #
270
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
271
+ # (defaults to current locale).
272
+ # * <tt>:precision</tt> - Sets the precision of the number
273
+ # (defaults to 3).
274
+ # * <tt>:significant</tt> - If +true+, precision will be the number
275
+ # of significant_digits. If +false+, the number of fractional
276
+ # digits (defaults to +true+)
277
+ # * <tt>:separator</tt> - Sets the separator between the
278
+ # fractional and integer digits (defaults to ".").
279
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
280
+ # to "").
281
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
282
+ # insignificant zeros after the decimal separator (defaults to
283
+ # +true+)
284
+ # * <tt>:units</tt> - A Hash of unit quantifier names. Or a
285
+ # string containing an i18n scope where to find this hash. It
286
+ # might have the following keys:
287
+ # * *integers*: <tt>:unit</tt>, <tt>:ten</tt>,
288
+ # <tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>,
289
+ # <tt>:billion</tt>, <tt>:trillion</tt>,
290
+ # <tt>:quadrillion</tt>
291
+ # * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>,
292
+ # <tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>,
293
+ # <tt>:pico</tt>, <tt>:femto</tt>
294
+ # * <tt>:format</tt> - Sets the format of the output string
295
+ # (defaults to "%n %u"). The field types are:
296
+ # * %u - The quantifier (ex.: 'thousand')
297
+ # * %n - The number
298
+ #
299
+ # ==== Examples
300
+ #
301
+ # number_to_human(123) # => "123"
302
+ # number_to_human(1234) # => "1.23 Thousand"
303
+ # number_to_human(12345) # => "12.3 Thousand"
304
+ # number_to_human(1234567) # => "1.23 Million"
305
+ # number_to_human(1234567890) # => "1.23 Billion"
306
+ # number_to_human(1234567890123) # => "1.23 Trillion"
307
+ # number_to_human(1234567890123456) # => "1.23 Quadrillion"
308
+ # number_to_human(1234567890123456789) # => "1230 Quadrillion"
309
+ # number_to_human(489939, precision: 2) # => "490 Thousand"
310
+ # number_to_human(489939, precision: 4) # => "489.9 Thousand"
311
+ # number_to_human(1234567, precision: 4,
312
+ # significant: false) # => "1.2346 Million"
313
+ # number_to_human(1234567, precision: 1,
314
+ # separator: ',',
315
+ # significant: false) # => "1,2 Million"
316
+ #
317
+ # number_to_human(500000000, precision: 5) # => "500 Million"
318
+ # number_to_human(12345012345, significant: false) # => "12.345 Billion"
319
+ #
320
+ # Non-significant zeros after the decimal separator are stripped
321
+ # out by default (set <tt>:strip_insignificant_zeros</tt> to
322
+ # +false+ to change that):
323
+ #
324
+ # number_to_human(12.00001) # => "12"
325
+ # number_to_human(12.00001, strip_insignificant_zeros: false) # => "12.0"
326
+ #
327
+ # ==== Custom Unit Quantifiers
328
+ #
329
+ # You can also use your own custom unit quantifiers:
330
+ # number_to_human(500000, units: { unit: 'ml', thousand: 'lt' }) # => "500 lt"
331
+ #
332
+ # If in your I18n locale you have:
333
+ #
334
+ # distance:
335
+ # centi:
336
+ # one: "centimeter"
337
+ # other: "centimeters"
338
+ # unit:
339
+ # one: "meter"
340
+ # other: "meters"
341
+ # thousand:
342
+ # one: "kilometer"
343
+ # other: "kilometers"
344
+ # billion: "gazillion-distance"
345
+ #
346
+ # Then you could do:
347
+ #
348
+ # number_to_human(543934, units: :distance) # => "544 kilometers"
349
+ # number_to_human(54393498, units: :distance) # => "54400 kilometers"
350
+ # number_to_human(54393498000, units: :distance) # => "54.4 gazillion-distance"
351
+ # number_to_human(343, units: :distance, precision: 1) # => "300 meters"
352
+ # number_to_human(1, units: :distance) # => "1 meter"
353
+ # number_to_human(0.34, units: :distance) # => "34 centimeters"
354
+ def number_to_human(number, options = {})
355
+ NumberToHumanConverter.convert(number, options)
356
+ end
357
+ end
358
+ end