activesupport 5.0.7.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (236) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1013 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +39 -0
  5. data/lib/active_support.rb +99 -0
  6. data/lib/active_support/all.rb +3 -0
  7. data/lib/active_support/array_inquirer.rb +44 -0
  8. data/lib/active_support/backtrace_cleaner.rb +103 -0
  9. data/lib/active_support/benchmarkable.rb +49 -0
  10. data/lib/active_support/builder.rb +6 -0
  11. data/lib/active_support/cache.rb +701 -0
  12. data/lib/active_support/cache/file_store.rb +204 -0
  13. data/lib/active_support/cache/mem_cache_store.rb +207 -0
  14. data/lib/active_support/cache/memory_store.rb +167 -0
  15. data/lib/active_support/cache/null_store.rb +41 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +172 -0
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
  18. data/lib/active_support/callbacks.rb +791 -0
  19. data/lib/active_support/concern.rb +142 -0
  20. data/lib/active_support/concurrency/latch.rb +26 -0
  21. data/lib/active_support/concurrency/share_lock.rb +226 -0
  22. data/lib/active_support/configurable.rb +148 -0
  23. data/lib/active_support/core_ext.rb +4 -0
  24. data/lib/active_support/core_ext/array.rb +7 -0
  25. data/lib/active_support/core_ext/array/access.rb +90 -0
  26. data/lib/active_support/core_ext/array/conversions.rb +211 -0
  27. data/lib/active_support/core_ext/array/extract_options.rb +29 -0
  28. data/lib/active_support/core_ext/array/grouping.rb +107 -0
  29. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  30. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +46 -0
  32. data/lib/active_support/core_ext/benchmark.rb +14 -0
  33. data/lib/active_support/core_ext/big_decimal.rb +1 -0
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  35. data/lib/active_support/core_ext/class.rb +2 -0
  36. data/lib/active_support/core_ext/class/attribute.rb +128 -0
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -0
  38. data/lib/active_support/core_ext/class/subclasses.rb +41 -0
  39. data/lib/active_support/core_ext/date.rb +5 -0
  40. data/lib/active_support/core_ext/date/acts_like.rb +8 -0
  41. data/lib/active_support/core_ext/date/blank.rb +12 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +143 -0
  43. data/lib/active_support/core_ext/date/conversions.rb +95 -0
  44. data/lib/active_support/core_ext/date/zones.rb +6 -0
  45. data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
  46. data/lib/active_support/core_ext/date_and_time/compatibility.rb +14 -0
  47. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  48. data/lib/active_support/core_ext/date_time.rb +5 -0
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +14 -0
  50. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +199 -0
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  53. data/lib/active_support/core_ext/date_time/conversions.rb +105 -0
  54. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  55. data/lib/active_support/core_ext/enumerable.rb +146 -0
  56. data/lib/active_support/core_ext/file.rb +1 -0
  57. data/lib/active_support/core_ext/file/atomic.rb +68 -0
  58. data/lib/active_support/core_ext/hash.rb +9 -0
  59. data/lib/active_support/core_ext/hash/compact.rb +24 -0
  60. data/lib/active_support/core_ext/hash/conversions.rb +262 -0
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +38 -0
  62. data/lib/active_support/core_ext/hash/except.rb +22 -0
  63. data/lib/active_support/core_ext/hash/indifferent_access.rb +23 -0
  64. data/lib/active_support/core_ext/hash/keys.rb +170 -0
  65. data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -0
  66. data/lib/active_support/core_ext/hash/slice.rb +48 -0
  67. data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
  68. data/lib/active_support/core_ext/integer.rb +3 -0
  69. data/lib/active_support/core_ext/integer/inflections.rb +29 -0
  70. data/lib/active_support/core_ext/integer/multiple.rb +10 -0
  71. data/lib/active_support/core_ext/integer/time.rb +29 -0
  72. data/lib/active_support/core_ext/kernel.rb +4 -0
  73. data/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
  74. data/lib/active_support/core_ext/kernel/concern.rb +12 -0
  75. data/lib/active_support/core_ext/kernel/debugger.rb +3 -0
  76. data/lib/active_support/core_ext/kernel/reporting.rb +43 -0
  77. data/lib/active_support/core_ext/kernel/singleton_class.rb +6 -0
  78. data/lib/active_support/core_ext/load_error.rb +31 -0
  79. data/lib/active_support/core_ext/marshal.rb +22 -0
  80. data/lib/active_support/core_ext/module.rb +12 -0
  81. data/lib/active_support/core_ext/module/aliasing.rb +74 -0
  82. data/lib/active_support/core_ext/module/anonymous.rb +28 -0
  83. data/lib/active_support/core_ext/module/attr_internal.rb +36 -0
  84. data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
  85. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  86. data/lib/active_support/core_ext/module/concerning.rb +135 -0
  87. data/lib/active_support/core_ext/module/delegation.rb +216 -0
  88. data/lib/active_support/core_ext/module/deprecation.rb +23 -0
  89. data/lib/active_support/core_ext/module/introspection.rb +68 -0
  90. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
  91. data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
  92. data/lib/active_support/core_ext/module/reachable.rb +8 -0
  93. data/lib/active_support/core_ext/module/remove_method.rb +35 -0
  94. data/lib/active_support/core_ext/name_error.rb +31 -0
  95. data/lib/active_support/core_ext/numeric.rb +4 -0
  96. data/lib/active_support/core_ext/numeric/bytes.rb +64 -0
  97. data/lib/active_support/core_ext/numeric/conversions.rb +144 -0
  98. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  99. data/lib/active_support/core_ext/numeric/time.rb +74 -0
  100. data/lib/active_support/core_ext/object.rb +14 -0
  101. data/lib/active_support/core_ext/object/acts_like.rb +10 -0
  102. data/lib/active_support/core_ext/object/blank.rb +143 -0
  103. data/lib/active_support/core_ext/object/conversions.rb +4 -0
  104. data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
  105. data/lib/active_support/core_ext/object/duplicable.rb +124 -0
  106. data/lib/active_support/core_ext/object/inclusion.rb +27 -0
  107. data/lib/active_support/core_ext/object/instance_variables.rb +28 -0
  108. data/lib/active_support/core_ext/object/json.rb +205 -0
  109. data/lib/active_support/core_ext/object/to_param.rb +1 -0
  110. data/lib/active_support/core_ext/object/to_query.rb +84 -0
  111. data/lib/active_support/core_ext/object/try.rb +146 -0
  112. data/lib/active_support/core_ext/object/with_options.rb +69 -0
  113. data/lib/active_support/core_ext/range.rb +4 -0
  114. data/lib/active_support/core_ext/range/conversions.rb +31 -0
  115. data/lib/active_support/core_ext/range/each.rb +21 -0
  116. data/lib/active_support/core_ext/range/include_range.rb +23 -0
  117. data/lib/active_support/core_ext/range/overlaps.rb +8 -0
  118. data/lib/active_support/core_ext/regexp.rb +5 -0
  119. data/lib/active_support/core_ext/securerandom.rb +23 -0
  120. data/lib/active_support/core_ext/string.rb +13 -0
  121. data/lib/active_support/core_ext/string/access.rb +104 -0
  122. data/lib/active_support/core_ext/string/behavior.rb +6 -0
  123. data/lib/active_support/core_ext/string/conversions.rb +57 -0
  124. data/lib/active_support/core_ext/string/exclude.rb +11 -0
  125. data/lib/active_support/core_ext/string/filters.rb +102 -0
  126. data/lib/active_support/core_ext/string/indent.rb +43 -0
  127. data/lib/active_support/core_ext/string/inflections.rb +244 -0
  128. data/lib/active_support/core_ext/string/inquiry.rb +13 -0
  129. data/lib/active_support/core_ext/string/multibyte.rb +53 -0
  130. data/lib/active_support/core_ext/string/output_safety.rb +260 -0
  131. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -0
  132. data/lib/active_support/core_ext/string/strip.rb +23 -0
  133. data/lib/active_support/core_ext/string/zones.rb +14 -0
  134. data/lib/active_support/core_ext/struct.rb +3 -0
  135. data/lib/active_support/core_ext/time.rb +5 -0
  136. data/lib/active_support/core_ext/time/acts_like.rb +8 -0
  137. data/lib/active_support/core_ext/time/calculations.rb +290 -0
  138. data/lib/active_support/core_ext/time/compatibility.rb +14 -0
  139. data/lib/active_support/core_ext/time/conversions.rb +67 -0
  140. data/lib/active_support/core_ext/time/marshal.rb +3 -0
  141. data/lib/active_support/core_ext/time/zones.rb +111 -0
  142. data/lib/active_support/core_ext/uri.rb +24 -0
  143. data/lib/active_support/dependencies.rb +755 -0
  144. data/lib/active_support/dependencies/autoload.rb +77 -0
  145. data/lib/active_support/dependencies/interlock.rb +55 -0
  146. data/lib/active_support/deprecation.rb +43 -0
  147. data/lib/active_support/deprecation/behaviors.rb +90 -0
  148. data/lib/active_support/deprecation/instance_delegator.rb +37 -0
  149. data/lib/active_support/deprecation/method_wrappers.rb +70 -0
  150. data/lib/active_support/deprecation/proxy_wrappers.rb +149 -0
  151. data/lib/active_support/deprecation/reporting.rb +112 -0
  152. data/lib/active_support/descendants_tracker.rb +60 -0
  153. data/lib/active_support/duration.rb +235 -0
  154. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  155. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  156. data/lib/active_support/evented_file_update_checker.rb +199 -0
  157. data/lib/active_support/execution_wrapper.rb +126 -0
  158. data/lib/active_support/executor.rb +6 -0
  159. data/lib/active_support/file_update_checker.rb +157 -0
  160. data/lib/active_support/gem_version.rb +15 -0
  161. data/lib/active_support/gzip.rb +36 -0
  162. data/lib/active_support/hash_with_indifferent_access.rb +329 -0
  163. data/lib/active_support/i18n.rb +13 -0
  164. data/lib/active_support/i18n_railtie.rb +115 -0
  165. data/lib/active_support/inflections.rb +70 -0
  166. data/lib/active_support/inflector.rb +7 -0
  167. data/lib/active_support/inflector/inflections.rb +242 -0
  168. data/lib/active_support/inflector/methods.rb +390 -0
  169. data/lib/active_support/inflector/transliterate.rb +112 -0
  170. data/lib/active_support/json.rb +2 -0
  171. data/lib/active_support/json/decoding.rb +74 -0
  172. data/lib/active_support/json/encoding.rb +127 -0
  173. data/lib/active_support/key_generator.rb +71 -0
  174. data/lib/active_support/lazy_load_hooks.rb +76 -0
  175. data/lib/active_support/locale/en.yml +135 -0
  176. data/lib/active_support/log_subscriber.rb +109 -0
  177. data/lib/active_support/log_subscriber/test_helper.rb +104 -0
  178. data/lib/active_support/logger.rb +106 -0
  179. data/lib/active_support/logger_silence.rb +28 -0
  180. data/lib/active_support/logger_thread_safe_level.rb +31 -0
  181. data/lib/active_support/message_encryptor.rb +114 -0
  182. data/lib/active_support/message_verifier.rb +134 -0
  183. data/lib/active_support/multibyte.rb +21 -0
  184. data/lib/active_support/multibyte/chars.rb +231 -0
  185. data/lib/active_support/multibyte/unicode.rb +413 -0
  186. data/lib/active_support/notifications.rb +212 -0
  187. data/lib/active_support/notifications/fanout.rb +157 -0
  188. data/lib/active_support/notifications/instrumenter.rb +91 -0
  189. data/lib/active_support/number_helper.rb +368 -0
  190. data/lib/active_support/number_helper/number_converter.rb +182 -0
  191. data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
  192. data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -0
  193. data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
  194. data/lib/active_support/number_helper/number_to_human_size_converter.rb +62 -0
  195. data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
  196. data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
  197. data/lib/active_support/number_helper/number_to_rounded_converter.rb +92 -0
  198. data/lib/active_support/option_merger.rb +25 -0
  199. data/lib/active_support/ordered_hash.rb +48 -0
  200. data/lib/active_support/ordered_options.rb +81 -0
  201. data/lib/active_support/per_thread_registry.rb +58 -0
  202. data/lib/active_support/proxy_object.rb +13 -0
  203. data/lib/active_support/rails.rb +27 -0
  204. data/lib/active_support/railtie.rb +51 -0
  205. data/lib/active_support/reloader.rb +129 -0
  206. data/lib/active_support/rescuable.rb +173 -0
  207. data/lib/active_support/security_utils.rb +27 -0
  208. data/lib/active_support/string_inquirer.rb +26 -0
  209. data/lib/active_support/subscriber.rb +120 -0
  210. data/lib/active_support/tagged_logging.rb +77 -0
  211. data/lib/active_support/test_case.rb +88 -0
  212. data/lib/active_support/testing/assertions.rb +99 -0
  213. data/lib/active_support/testing/autorun.rb +5 -0
  214. data/lib/active_support/testing/constant_lookup.rb +50 -0
  215. data/lib/active_support/testing/declarative.rb +26 -0
  216. data/lib/active_support/testing/deprecation.rb +36 -0
  217. data/lib/active_support/testing/file_fixtures.rb +34 -0
  218. data/lib/active_support/testing/isolation.rb +115 -0
  219. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  220. data/lib/active_support/testing/setup_and_teardown.rb +50 -0
  221. data/lib/active_support/testing/stream.rb +42 -0
  222. data/lib/active_support/testing/tagged_logging.rb +25 -0
  223. data/lib/active_support/testing/time_helpers.rb +136 -0
  224. data/lib/active_support/time.rb +18 -0
  225. data/lib/active_support/time_with_zone.rb +511 -0
  226. data/lib/active_support/values/time_zone.rb +484 -0
  227. data/lib/active_support/values/unicode_tables.dat +0 -0
  228. data/lib/active_support/version.rb +8 -0
  229. data/lib/active_support/xml_mini.rb +209 -0
  230. data/lib/active_support/xml_mini/jdom.rb +181 -0
  231. data/lib/active_support/xml_mini/libxml.rb +77 -0
  232. data/lib/active_support/xml_mini/libxmlsax.rb +82 -0
  233. data/lib/active_support/xml_mini/nokogiri.rb +81 -0
  234. data/lib/active_support/xml_mini/nokogirisax.rb +85 -0
  235. data/lib/active_support/xml_mini/rexml.rb +128 -0
  236. metadata +350 -0
@@ -0,0 +1,157 @@
1
+ require 'mutex_m'
2
+ require 'concurrent/map'
3
+
4
+ module ActiveSupport
5
+ module Notifications
6
+ # This is a default queue implementation that ships with Notifications.
7
+ # It just pushes events to all registered log subscribers.
8
+ #
9
+ # This class is thread safe. All methods are reentrant.
10
+ class Fanout
11
+ include Mutex_m
12
+
13
+ def initialize
14
+ @subscribers = []
15
+ @listeners_for = Concurrent::Map.new
16
+ super
17
+ end
18
+
19
+ def subscribe(pattern = nil, block = Proc.new)
20
+ subscriber = Subscribers.new pattern, block
21
+ synchronize do
22
+ @subscribers << subscriber
23
+ @listeners_for.clear
24
+ end
25
+ subscriber
26
+ end
27
+
28
+ def unsubscribe(subscriber_or_name)
29
+ synchronize do
30
+ case subscriber_or_name
31
+ when String
32
+ @subscribers.reject! { |s| s.matches?(subscriber_or_name) }
33
+ else
34
+ @subscribers.delete(subscriber_or_name)
35
+ end
36
+
37
+ @listeners_for.clear
38
+ end
39
+ end
40
+
41
+ def start(name, id, payload)
42
+ listeners_for(name).each { |s| s.start(name, id, payload) }
43
+ end
44
+
45
+ def finish(name, id, payload, listeners = listeners_for(name))
46
+ listeners.each { |s| s.finish(name, id, payload) }
47
+ end
48
+
49
+ def publish(name, *args)
50
+ listeners_for(name).each { |s| s.publish(name, *args) }
51
+ end
52
+
53
+ def listeners_for(name)
54
+ # this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics)
55
+ @listeners_for[name] || synchronize do
56
+ # use synchronisation when accessing @subscribers
57
+ @listeners_for[name] ||= @subscribers.select { |s| s.subscribed_to?(name) }
58
+ end
59
+ end
60
+
61
+ def listening?(name)
62
+ listeners_for(name).any?
63
+ end
64
+
65
+ # This is a sync queue, so there is no waiting.
66
+ def wait
67
+ end
68
+
69
+ module Subscribers # :nodoc:
70
+ def self.new(pattern, listener)
71
+ if listener.respond_to?(:start) and listener.respond_to?(:finish)
72
+ subscriber = Evented.new pattern, listener
73
+ else
74
+ subscriber = Timed.new pattern, listener
75
+ end
76
+
77
+ unless pattern
78
+ AllMessages.new(subscriber)
79
+ else
80
+ subscriber
81
+ end
82
+ end
83
+
84
+ class Evented #:nodoc:
85
+ def initialize(pattern, delegate)
86
+ @pattern = pattern
87
+ @delegate = delegate
88
+ @can_publish = delegate.respond_to?(:publish)
89
+ end
90
+
91
+ def publish(name, *args)
92
+ if @can_publish
93
+ @delegate.publish name, *args
94
+ end
95
+ end
96
+
97
+ def start(name, id, payload)
98
+ @delegate.start name, id, payload
99
+ end
100
+
101
+ def finish(name, id, payload)
102
+ @delegate.finish name, id, payload
103
+ end
104
+
105
+ def subscribed_to?(name)
106
+ @pattern === name
107
+ end
108
+
109
+ def matches?(name)
110
+ @pattern && @pattern === name
111
+ end
112
+ end
113
+
114
+ class Timed < Evented # :nodoc:
115
+ def publish(name, *args)
116
+ @delegate.call name, *args
117
+ end
118
+
119
+ def start(name, id, payload)
120
+ timestack = Thread.current[:_timestack] ||= []
121
+ timestack.push Time.now
122
+ end
123
+
124
+ def finish(name, id, payload)
125
+ timestack = Thread.current[:_timestack]
126
+ started = timestack.pop
127
+ @delegate.call(name, started, Time.now, id, payload)
128
+ end
129
+ end
130
+
131
+ class AllMessages # :nodoc:
132
+ def initialize(delegate)
133
+ @delegate = delegate
134
+ end
135
+
136
+ def start(name, id, payload)
137
+ @delegate.start name, id, payload
138
+ end
139
+
140
+ def finish(name, id, payload)
141
+ @delegate.finish name, id, payload
142
+ end
143
+
144
+ def publish(name, *args)
145
+ @delegate.publish name, *args
146
+ end
147
+
148
+ def subscribed_to?(name)
149
+ true
150
+ end
151
+
152
+ alias :matches? :===
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,91 @@
1
+ require 'securerandom'
2
+
3
+ module ActiveSupport
4
+ module Notifications
5
+ # Instrumenters are stored in a thread local.
6
+ class Instrumenter
7
+ attr_reader :id
8
+
9
+ def initialize(notifier)
10
+ @id = unique_id
11
+ @notifier = notifier
12
+ end
13
+
14
+ # Instrument the given block by measuring the time taken to execute it
15
+ # and publish it. Notice that events get sent even if an error occurs
16
+ # in the passed-in block.
17
+ def instrument(name, payload={})
18
+ # some of the listeners might have state
19
+ listeners_state = start name, payload
20
+ begin
21
+ yield payload
22
+ rescue Exception => e
23
+ payload[:exception] = [e.class.name, e.message]
24
+ payload[:exception_object] = e
25
+ raise e
26
+ ensure
27
+ finish_with_state listeners_state, name, payload
28
+ end
29
+ end
30
+
31
+ # Send a start notification with +name+ and +payload+.
32
+ def start(name, payload)
33
+ @notifier.start name, @id, payload
34
+ end
35
+
36
+ # Send a finish notification with +name+ and +payload+.
37
+ def finish(name, payload)
38
+ @notifier.finish name, @id, payload
39
+ end
40
+
41
+ def finish_with_state(listeners_state, name, payload)
42
+ @notifier.finish name, @id, payload, listeners_state
43
+ end
44
+
45
+ private
46
+
47
+ def unique_id
48
+ SecureRandom.hex(10)
49
+ end
50
+ end
51
+
52
+ class Event
53
+ attr_reader :name, :time, :transaction_id, :payload, :children
54
+ attr_accessor :end
55
+
56
+ def initialize(name, start, ending, transaction_id, payload)
57
+ @name = name
58
+ @payload = payload.dup
59
+ @time = start
60
+ @transaction_id = transaction_id
61
+ @end = ending
62
+ @children = []
63
+ @duration = nil
64
+ end
65
+
66
+ # Returns the difference in milliseconds between when the execution of the
67
+ # event started and when it ended.
68
+ #
69
+ # ActiveSupport::Notifications.subscribe('wait') do |*args|
70
+ # @event = ActiveSupport::Notifications::Event.new(*args)
71
+ # end
72
+ #
73
+ # ActiveSupport::Notifications.instrument('wait') do
74
+ # sleep 1
75
+ # end
76
+ #
77
+ # @event.duration # => 1000.138
78
+ def duration
79
+ @duration ||= 1000.0 * (self.end - time)
80
+ end
81
+
82
+ def <<(event)
83
+ @children << event
84
+ end
85
+
86
+ def parent_of?(event)
87
+ @children.include? event
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,368 @@
1
+ module ActiveSupport
2
+ module NumberHelper
3
+ extend ActiveSupport::Autoload
4
+
5
+ eager_autoload do
6
+ autoload :NumberConverter
7
+ autoload :NumberToRoundedConverter
8
+ autoload :NumberToDelimitedConverter
9
+ autoload :NumberToHumanConverter
10
+ autoload :NumberToHumanSizeConverter
11
+ autoload :NumberToPhoneConverter
12
+ autoload :NumberToCurrencyConverter
13
+ autoload :NumberToPercentageConverter
14
+ end
15
+
16
+ extend self
17
+
18
+ # Formats a +number+ into a phone number (US by default e.g., (555)
19
+ # 123-9876). You can customize the format in the +options+ hash.
20
+ #
21
+ # ==== Options
22
+ #
23
+ # * <tt>:area_code</tt> - Adds parentheses around the area code.
24
+ # * <tt>:delimiter</tt> - Specifies the delimiter to use
25
+ # (defaults to "-").
26
+ # * <tt>:extension</tt> - Specifies an extension to add to the
27
+ # end of the generated number.
28
+ # * <tt>:country_code</tt> - Sets the country code for the phone
29
+ # number.
30
+ # * <tt>:pattern</tt> - Specifies how the number is divided into three
31
+ # groups with the custom regexp to override the default format.
32
+ # ==== Examples
33
+ #
34
+ # number_to_phone(5551234) # => "555-1234"
35
+ # number_to_phone('5551234') # => "555-1234"
36
+ # number_to_phone(1235551234) # => "123-555-1234"
37
+ # number_to_phone(1235551234, area_code: true) # => "(123) 555-1234"
38
+ # number_to_phone(1235551234, delimiter: ' ') # => "123 555 1234"
39
+ # number_to_phone(1235551234, area_code: true, extension: 555) # => "(123) 555-1234 x 555"
40
+ # number_to_phone(1235551234, country_code: 1) # => "+1-123-555-1234"
41
+ # number_to_phone('123a456') # => "123a456"
42
+ #
43
+ # number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: '.')
44
+ # # => "+1.123.555.1234 x 1343"
45
+ #
46
+ # number_to_phone(75561234567, pattern: /(\d{1,4})(\d{4})(\d{4})$/, area_code: true)
47
+ # # => "(755) 6123-4567"
48
+ # number_to_phone(13312345678, pattern: /(\d{3})(\d{4})(\d{4})$/))
49
+ # # => "133-1234-5678"
50
+ def number_to_phone(number, options = {})
51
+ NumberToPhoneConverter.convert(number, options)
52
+ end
53
+
54
+ # Formats a +number+ into a currency string (e.g., $13.65). You
55
+ # can customize the format in the +options+ hash.
56
+ #
57
+ # The currency unit and number formatting of the current locale will be used
58
+ # unless otherwise specified in the provided options. No currency conversion
59
+ # is performed. If the user is given a way to change their locale, they will
60
+ # also be able to change the relative value of the currency displayed with
61
+ # this helper. If your application will ever support multiple locales, you
62
+ # may want to specify a constant <tt>:locale</tt> option or consider
63
+ # using a library capable of currency conversion.
64
+ #
65
+ # ==== Options
66
+ #
67
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
68
+ # (defaults to current locale).
69
+ # * <tt>:precision</tt> - Sets the level of precision (defaults
70
+ # to 2).
71
+ # * <tt>:unit</tt> - Sets the denomination of the currency
72
+ # (defaults to "$").
73
+ # * <tt>:separator</tt> - Sets the separator between the units
74
+ # (defaults to ".").
75
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
76
+ # to ",").
77
+ # * <tt>:format</tt> - Sets the format for non-negative numbers
78
+ # (defaults to "%u%n"). Fields are <tt>%u</tt> for the
79
+ # currency, and <tt>%n</tt> for the number.
80
+ # * <tt>:negative_format</tt> - Sets the format for negative
81
+ # numbers (defaults to prepending an hyphen to the formatted
82
+ # number given by <tt>:format</tt>). Accepts the same fields
83
+ # than <tt>:format</tt>, except <tt>%n</tt> is here the
84
+ # absolute value of the number.
85
+ #
86
+ # ==== Examples
87
+ #
88
+ # number_to_currency(1234567890.50) # => "$1,234,567,890.50"
89
+ # number_to_currency(1234567890.506) # => "$1,234,567,890.51"
90
+ # number_to_currency(1234567890.506, precision: 3) # => "$1,234,567,890.506"
91
+ # number_to_currency(1234567890.506, locale: :fr) # => "1 234 567 890,51 €"
92
+ # number_to_currency('123a456') # => "$123a456"
93
+ #
94
+ # number_to_currency(-1234567890.50, negative_format: '(%u%n)')
95
+ # # => "($1,234,567,890.50)"
96
+ # number_to_currency(1234567890.50, unit: '&pound;', separator: ',', delimiter: '')
97
+ # # => "&pound;1234567890,50"
98
+ # number_to_currency(1234567890.50, unit: '&pound;', separator: ',', delimiter: '', format: '%n %u')
99
+ # # => "1234567890,50 &pound;"
100
+ def number_to_currency(number, options = {})
101
+ NumberToCurrencyConverter.convert(number, options)
102
+ end
103
+
104
+ # Formats a +number+ as a percentage string (e.g., 65%). You can
105
+ # customize the format in the +options+ hash.
106
+ #
107
+ # ==== Options
108
+ #
109
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
110
+ # (defaults to current locale).
111
+ # * <tt>:precision</tt> - Sets the precision of the number
112
+ # (defaults to 3). Keeps the number's precision if nil.
113
+ # * <tt>:significant</tt> - If +true+, precision will be the number
114
+ # of significant_digits. If +false+, the number of fractional
115
+ # digits (defaults to +false+).
116
+ # * <tt>:separator</tt> - Sets the separator between the
117
+ # fractional and integer digits (defaults to ".").
118
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
119
+ # to "").
120
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
121
+ # insignificant zeros after the decimal separator (defaults to
122
+ # +false+).
123
+ # * <tt>:format</tt> - Specifies the format of the percentage
124
+ # string The number field is <tt>%n</tt> (defaults to "%n%").
125
+ #
126
+ # ==== Examples
127
+ #
128
+ # number_to_percentage(100) # => "100.000%"
129
+ # number_to_percentage('98') # => "98.000%"
130
+ # number_to_percentage(100, precision: 0) # => "100%"
131
+ # number_to_percentage(1000, delimiter: '.', separator: ',') # => "1.000,000%"
132
+ # number_to_percentage(302.24398923423, precision: 5) # => "302.24399%"
133
+ # number_to_percentage(1000, locale: :fr) # => "1000,000%"
134
+ # number_to_percentage(1000, precision: nil) # => "1000%"
135
+ # number_to_percentage('98a') # => "98a%"
136
+ # number_to_percentage(100, format: '%n %') # => "100.000 %"
137
+ def number_to_percentage(number, options = {})
138
+ NumberToPercentageConverter.convert(number, options)
139
+ end
140
+
141
+ # Formats a +number+ with grouped thousands using +delimiter+
142
+ # (e.g., 12,324). You can customize the format in the +options+
143
+ # hash.
144
+ #
145
+ # ==== Options
146
+ #
147
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
148
+ # (defaults to current locale).
149
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
150
+ # to ",").
151
+ # * <tt>:separator</tt> - Sets the separator between the
152
+ # fractional and integer digits (defaults to ".").
153
+ # * <tt>:delimiter_pattern</tt> - Sets a custom regular expression used for
154
+ # deriving the placement of delimiter. Helpful when using currency formats
155
+ # like INR.
156
+ #
157
+ # ==== Examples
158
+ #
159
+ # number_to_delimited(12345678) # => "12,345,678"
160
+ # number_to_delimited('123456') # => "123,456"
161
+ # number_to_delimited(12345678.05) # => "12,345,678.05"
162
+ # number_to_delimited(12345678, delimiter: '.') # => "12.345.678"
163
+ # number_to_delimited(12345678, delimiter: ',') # => "12,345,678"
164
+ # number_to_delimited(12345678.05, separator: ' ') # => "12,345,678 05"
165
+ # number_to_delimited(12345678.05, locale: :fr) # => "12 345 678,05"
166
+ # number_to_delimited('112a') # => "112a"
167
+ # number_to_delimited(98765432.98, delimiter: ' ', separator: ',')
168
+ # # => "98 765 432,98"
169
+ # number_to_delimited("123456.78",
170
+ # delimiter_pattern: /(\d+?)(?=(\d\d)+(\d)(?!\d))/)
171
+ # # => "1,23,456.78"
172
+ def number_to_delimited(number, options = {})
173
+ NumberToDelimitedConverter.convert(number, options)
174
+ end
175
+
176
+ # Formats a +number+ with the specified level of
177
+ # <tt>:precision</tt> (e.g., 112.32 has a precision of 2 if
178
+ # +:significant+ is +false+, and 5 if +:significant+ is +true+).
179
+ # You can customize the format in the +options+ hash.
180
+ #
181
+ # ==== Options
182
+ #
183
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
184
+ # (defaults to current locale).
185
+ # * <tt>:precision</tt> - Sets the precision of the number
186
+ # (defaults to 3). Keeps the number's precision if nil.
187
+ # * <tt>:significant</tt> - If +true+, precision will be the number
188
+ # of significant_digits. If +false+, the number of fractional
189
+ # digits (defaults to +false+).
190
+ # * <tt>:separator</tt> - Sets the separator between the
191
+ # fractional and integer digits (defaults to ".").
192
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
193
+ # to "").
194
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
195
+ # insignificant zeros after the decimal separator (defaults to
196
+ # +false+).
197
+ #
198
+ # ==== Examples
199
+ #
200
+ # number_to_rounded(111.2345) # => "111.235"
201
+ # number_to_rounded(111.2345, precision: 2) # => "111.23"
202
+ # number_to_rounded(13, precision: 5) # => "13.00000"
203
+ # number_to_rounded(389.32314, precision: 0) # => "389"
204
+ # number_to_rounded(111.2345, significant: true) # => "111"
205
+ # number_to_rounded(111.2345, precision: 1, significant: true) # => "100"
206
+ # number_to_rounded(13, precision: 5, significant: true) # => "13.000"
207
+ # number_to_rounded(13, precision: nil) # => "13"
208
+ # number_to_rounded(111.234, locale: :fr) # => "111,234"
209
+ #
210
+ # number_to_rounded(13, precision: 5, significant: true, strip_insignificant_zeros: true)
211
+ # # => "13"
212
+ #
213
+ # number_to_rounded(389.32314, precision: 4, significant: true) # => "389.3"
214
+ # number_to_rounded(1111.2345, precision: 2, separator: ',', delimiter: '.')
215
+ # # => "1.111,23"
216
+ def number_to_rounded(number, options = {})
217
+ NumberToRoundedConverter.convert(number, options)
218
+ end
219
+
220
+ # Formats the bytes in +number+ into a more understandable
221
+ # representation (e.g., giving it 1500 yields 1.5 KB). This
222
+ # method is useful for reporting file sizes to users. You can
223
+ # customize the format in the +options+ hash.
224
+ #
225
+ # See <tt>number_to_human</tt> if you want to pretty-print a
226
+ # generic number.
227
+ #
228
+ # ==== Options
229
+ #
230
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
231
+ # (defaults to current locale).
232
+ # * <tt>:precision</tt> - Sets the precision of the number
233
+ # (defaults to 3).
234
+ # * <tt>:significant</tt> - If +true+, precision will be the number
235
+ # of significant_digits. If +false+, the number of fractional
236
+ # digits (defaults to +true+)
237
+ # * <tt>:separator</tt> - Sets the separator between the
238
+ # fractional and integer digits (defaults to ".").
239
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
240
+ # to "").
241
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
242
+ # insignificant zeros after the decimal separator (defaults to
243
+ # +true+)
244
+ #
245
+ # ==== Examples
246
+ #
247
+ # number_to_human_size(123) # => "123 Bytes"
248
+ # number_to_human_size(1234) # => "1.21 KB"
249
+ # number_to_human_size(12345) # => "12.1 KB"
250
+ # number_to_human_size(1234567) # => "1.18 MB"
251
+ # number_to_human_size(1234567890) # => "1.15 GB"
252
+ # number_to_human_size(1234567890123) # => "1.12 TB"
253
+ # number_to_human_size(1234567890123456) # => "1.1 PB"
254
+ # number_to_human_size(1234567890123456789) # => "1.07 EB"
255
+ # number_to_human_size(1234567, precision: 2) # => "1.2 MB"
256
+ # number_to_human_size(483989, precision: 2) # => "470 KB"
257
+ # number_to_human_size(1234567, precision: 2, separator: ',') # => "1,2 MB"
258
+ # number_to_human_size(1234567890123, precision: 5) # => "1.1228 TB"
259
+ # number_to_human_size(524288000, precision: 5) # => "500 MB"
260
+ def number_to_human_size(number, options = {})
261
+ NumberToHumanSizeConverter.convert(number, options)
262
+ end
263
+
264
+ # Pretty prints (formats and approximates) a number in a way it
265
+ # is more readable by humans (eg.: 1200000000 becomes "1.2
266
+ # Billion"). This is useful for numbers that can get very large
267
+ # (and too hard to read).
268
+ #
269
+ # See <tt>number_to_human_size</tt> if you want to print a file
270
+ # size.
271
+ #
272
+ # You can also define your own unit-quantifier names if you want
273
+ # to use other decimal units (eg.: 1500 becomes "1.5
274
+ # kilometers", 0.150 becomes "150 milliliters", etc). You may
275
+ # define a wide range of unit quantifiers, even fractional ones
276
+ # (centi, deci, mili, etc).
277
+ #
278
+ # ==== Options
279
+ #
280
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
281
+ # (defaults to current locale).
282
+ # * <tt>:precision</tt> - Sets the precision of the number
283
+ # (defaults to 3).
284
+ # * <tt>:significant</tt> - If +true+, precision will be the number
285
+ # of significant_digits. If +false+, the number of fractional
286
+ # digits (defaults to +true+)
287
+ # * <tt>:separator</tt> - Sets the separator between the
288
+ # fractional and integer digits (defaults to ".").
289
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
290
+ # to "").
291
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
292
+ # insignificant zeros after the decimal separator (defaults to
293
+ # +true+)
294
+ # * <tt>:units</tt> - A Hash of unit quantifier names. Or a
295
+ # string containing an i18n scope where to find this hash. It
296
+ # might have the following keys:
297
+ # * *integers*: <tt>:unit</tt>, <tt>:ten</tt>,
298
+ # <tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>,
299
+ # <tt>:billion</tt>, <tt>:trillion</tt>,
300
+ # <tt>:quadrillion</tt>
301
+ # * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>,
302
+ # <tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>,
303
+ # <tt>:pico</tt>, <tt>:femto</tt>
304
+ # * <tt>:format</tt> - Sets the format of the output string
305
+ # (defaults to "%n %u"). The field types are:
306
+ # * %u - The quantifier (ex.: 'thousand')
307
+ # * %n - The number
308
+ #
309
+ # ==== Examples
310
+ #
311
+ # number_to_human(123) # => "123"
312
+ # number_to_human(1234) # => "1.23 Thousand"
313
+ # number_to_human(12345) # => "12.3 Thousand"
314
+ # number_to_human(1234567) # => "1.23 Million"
315
+ # number_to_human(1234567890) # => "1.23 Billion"
316
+ # number_to_human(1234567890123) # => "1.23 Trillion"
317
+ # number_to_human(1234567890123456) # => "1.23 Quadrillion"
318
+ # number_to_human(1234567890123456789) # => "1230 Quadrillion"
319
+ # number_to_human(489939, precision: 2) # => "490 Thousand"
320
+ # number_to_human(489939, precision: 4) # => "489.9 Thousand"
321
+ # number_to_human(1234567, precision: 4,
322
+ # significant: false) # => "1.2346 Million"
323
+ # number_to_human(1234567, precision: 1,
324
+ # separator: ',',
325
+ # significant: false) # => "1,2 Million"
326
+ #
327
+ # number_to_human(500000000, precision: 5) # => "500 Million"
328
+ # number_to_human(12345012345, significant: false) # => "12.345 Billion"
329
+ #
330
+ # Non-significant zeros after the decimal separator are stripped
331
+ # out by default (set <tt>:strip_insignificant_zeros</tt> to
332
+ # +false+ to change that):
333
+ #
334
+ # number_to_human(12.00001) # => "12"
335
+ # number_to_human(12.00001, strip_insignificant_zeros: false) # => "12.0"
336
+ #
337
+ # ==== Custom Unit Quantifiers
338
+ #
339
+ # You can also use your own custom unit quantifiers:
340
+ # number_to_human(500000, units: { unit: 'ml', thousand: 'lt' }) # => "500 lt"
341
+ #
342
+ # If in your I18n locale you have:
343
+ #
344
+ # distance:
345
+ # centi:
346
+ # one: "centimeter"
347
+ # other: "centimeters"
348
+ # unit:
349
+ # one: "meter"
350
+ # other: "meters"
351
+ # thousand:
352
+ # one: "kilometer"
353
+ # other: "kilometers"
354
+ # billion: "gazillion-distance"
355
+ #
356
+ # Then you could do:
357
+ #
358
+ # number_to_human(543934, units: :distance) # => "544 kilometers"
359
+ # number_to_human(54393498, units: :distance) # => "54400 kilometers"
360
+ # number_to_human(54393498000, units: :distance) # => "54.4 gazillion-distance"
361
+ # number_to_human(343, units: :distance, precision: 1) # => "300 meters"
362
+ # number_to_human(1, units: :distance) # => "1 meter"
363
+ # number_to_human(0.34, units: :distance) # => "34 centimeters"
364
+ def number_to_human(number, options = {})
365
+ NumberToHumanConverter.convert(number, options)
366
+ end
367
+ end
368
+ end