activesupport 4.2.11.3 → 5.2.8.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 (256) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +435 -403
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +4 -5
  5. data/lib/active_support/all.rb +5 -3
  6. data/lib/active_support/array_inquirer.rb +48 -0
  7. data/lib/active_support/backtrace_cleaner.rb +7 -5
  8. data/lib/active_support/benchmarkable.rb +6 -4
  9. data/lib/active_support/builder.rb +3 -1
  10. data/lib/active_support/cache/file_store.rb +41 -35
  11. data/lib/active_support/cache/mem_cache_store.rb +91 -91
  12. data/lib/active_support/cache/memory_store.rb +27 -30
  13. data/lib/active_support/cache/null_store.rb +7 -8
  14. data/lib/active_support/cache/redis_cache_store.rb +466 -0
  15. data/lib/active_support/cache/strategy/local_cache.rb +67 -34
  16. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  17. data/lib/active_support/cache.rb +287 -196
  18. data/lib/active_support/callbacks.rb +640 -590
  19. data/lib/active_support/concern.rb +11 -5
  20. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
  21. data/lib/active_support/concurrency/share_lock.rb +227 -0
  22. data/lib/active_support/configurable.rb +8 -5
  23. data/lib/active_support/core_ext/array/access.rb +29 -1
  24. data/lib/active_support/core_ext/array/conversions.rb +22 -18
  25. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  26. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  27. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  28. data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
  29. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  30. data/lib/active_support/core_ext/array.rb +9 -6
  31. data/lib/active_support/core_ext/benchmark.rb +3 -1
  32. data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
  33. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  34. data/lib/active_support/core_ext/class/attribute.rb +41 -22
  35. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  36. data/lib/active_support/core_ext/class/subclasses.rb +20 -6
  37. data/lib/active_support/core_ext/class.rb +4 -3
  38. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  39. data/lib/active_support/core_ext/date/blank.rb +14 -0
  40. data/lib/active_support/core_ext/date/calculations.rb +11 -9
  41. data/lib/active_support/core_ext/date/conversions.rb +25 -23
  42. data/lib/active_support/core_ext/date/zones.rb +4 -2
  43. data/lib/active_support/core_ext/date.rb +6 -4
  44. data/lib/active_support/core_ext/date_and_time/calculations.rb +170 -58
  45. data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
  46. data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
  47. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  48. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  49. data/lib/active_support/core_ext/date_time/calculations.rb +36 -18
  50. data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
  51. data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
  52. data/lib/active_support/core_ext/date_time.rb +7 -5
  53. data/lib/active_support/core_ext/digest/uuid.rb +7 -5
  54. data/lib/active_support/core_ext/digest.rb +3 -0
  55. data/lib/active_support/core_ext/enumerable.rb +101 -33
  56. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  57. data/lib/active_support/core_ext/file.rb +3 -1
  58. data/lib/active_support/core_ext/hash/compact.rb +14 -9
  59. data/lib/active_support/core_ext/hash/conversions.rb +62 -41
  60. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  61. data/lib/active_support/core_ext/hash/except.rb +11 -8
  62. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  63. data/lib/active_support/core_ext/hash/keys.rb +33 -27
  64. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  65. data/lib/active_support/core_ext/hash/slice.rb +8 -8
  66. data/lib/active_support/core_ext/hash/transform_values.rb +14 -5
  67. data/lib/active_support/core_ext/hash.rb +11 -9
  68. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  69. data/lib/active_support/core_ext/integer/multiple.rb +2 -0
  70. data/lib/active_support/core_ext/integer/time.rb +11 -18
  71. data/lib/active_support/core_ext/integer.rb +5 -3
  72. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +5 -1
  74. data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +6 -5
  77. data/lib/active_support/core_ext/load_error.rb +3 -22
  78. data/lib/active_support/core_ext/marshal.rb +8 -8
  79. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  80. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  81. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
  84. data/lib/active_support/core_ext/module/concerning.rb +11 -12
  85. data/lib/active_support/core_ext/module/delegation.rb +98 -36
  86. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  87. data/lib/active_support/core_ext/module/introspection.rb +9 -9
  88. data/lib/active_support/core_ext/module/reachable.rb +5 -2
  89. data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
  90. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  91. data/lib/active_support/core_ext/module.rb +14 -11
  92. data/lib/active_support/core_ext/name_error.rb +22 -2
  93. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  94. data/lib/active_support/core_ext/numeric/conversions.rb +78 -81
  95. data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
  96. data/lib/active_support/core_ext/numeric/time.rb +35 -23
  97. data/lib/active_support/core_ext/numeric.rb +6 -3
  98. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  99. data/lib/active_support/core_ext/object/blank.rb +27 -2
  100. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  101. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  102. data/lib/active_support/core_ext/object/duplicable.rb +41 -14
  103. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  104. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  105. data/lib/active_support/core_ext/object/json.rb +49 -19
  106. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  107. data/lib/active_support/core_ext/object/to_query.rb +10 -5
  108. data/lib/active_support/core_ext/object/try.rb +69 -21
  109. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  110. data/lib/active_support/core_ext/object.rb +14 -13
  111. data/lib/active_support/core_ext/range/compare_range.rb +61 -0
  112. data/lib/active_support/core_ext/range/conversions.rb +27 -7
  113. data/lib/active_support/core_ext/range/each.rb +19 -17
  114. data/lib/active_support/core_ext/range/include_range.rb +2 -22
  115. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  116. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  117. data/lib/active_support/core_ext/range.rb +7 -4
  118. data/lib/active_support/core_ext/regexp.rb +6 -0
  119. data/lib/active_support/core_ext/securerandom.rb +25 -0
  120. data/lib/active_support/core_ext/string/access.rb +8 -6
  121. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  122. data/lib/active_support/core_ext/string/conversions.rb +7 -4
  123. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  124. data/lib/active_support/core_ext/string/filters.rb +6 -5
  125. data/lib/active_support/core_ext/string/indent.rb +6 -4
  126. data/lib/active_support/core_ext/string/inflections.rb +61 -24
  127. data/lib/active_support/core_ext/string/inquiry.rb +3 -1
  128. data/lib/active_support/core_ext/string/multibyte.rb +15 -7
  129. data/lib/active_support/core_ext/string/output_safety.rb +62 -38
  130. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  131. data/lib/active_support/core_ext/string/strip.rb +4 -5
  132. data/lib/active_support/core_ext/string/zones.rb +4 -2
  133. data/lib/active_support/core_ext/string.rb +15 -13
  134. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  135. data/lib/active_support/core_ext/time/calculations.rb +85 -51
  136. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  137. data/lib/active_support/core_ext/time/conversions.rb +20 -13
  138. data/lib/active_support/core_ext/time/zones.rb +41 -7
  139. data/lib/active_support/core_ext/time.rb +7 -6
  140. data/lib/active_support/core_ext/uri.rb +6 -8
  141. data/lib/active_support/core_ext.rb +3 -1
  142. data/lib/active_support/current_attributes.rb +195 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +57 -0
  145. data/lib/active_support/dependencies.rb +152 -161
  146. data/lib/active_support/deprecation/behaviors.rb +44 -11
  147. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  148. data/lib/active_support/deprecation/instance_delegator.rb +17 -2
  149. data/lib/active_support/deprecation/method_wrappers.rb +66 -20
  150. data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
  151. data/lib/active_support/deprecation/reporting.rb +32 -12
  152. data/lib/active_support/deprecation.rb +12 -9
  153. data/lib/active_support/descendants_tracker.rb +2 -0
  154. data/lib/active_support/digest.rb +20 -0
  155. data/lib/active_support/duration/iso8601_parser.rb +125 -0
  156. data/lib/active_support/duration/iso8601_serializer.rb +55 -0
  157. data/lib/active_support/duration.rb +314 -38
  158. data/lib/active_support/encrypted_configuration.rb +49 -0
  159. data/lib/active_support/encrypted_file.rb +99 -0
  160. data/lib/active_support/evented_file_update_checker.rb +205 -0
  161. data/lib/active_support/execution_wrapper.rb +131 -0
  162. data/lib/active_support/executor.rb +8 -0
  163. data/lib/active_support/file_update_checker.rb +63 -37
  164. data/lib/active_support/gem_version.rb +6 -4
  165. data/lib/active_support/gzip.rb +7 -5
  166. data/lib/active_support/hash_with_indifferent_access.rb +123 -28
  167. data/lib/active_support/i18n.rb +8 -6
  168. data/lib/active_support/i18n_railtie.rb +37 -13
  169. data/lib/active_support/inflections.rb +13 -11
  170. data/lib/active_support/inflector/inflections.rb +61 -12
  171. data/lib/active_support/inflector/methods.rb +163 -136
  172. data/lib/active_support/inflector/transliterate.rb +48 -27
  173. data/lib/active_support/inflector.rb +7 -5
  174. data/lib/active_support/json/decoding.rb +16 -13
  175. data/lib/active_support/json/encoding.rb +11 -58
  176. data/lib/active_support/json.rb +4 -2
  177. data/lib/active_support/key_generator.rb +25 -25
  178. data/lib/active_support/lazy_load_hooks.rb +50 -20
  179. data/lib/active_support/locale/en.yml +2 -0
  180. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  181. data/lib/active_support/log_subscriber.rb +13 -10
  182. data/lib/active_support/logger.rb +8 -7
  183. data/lib/active_support/logger_silence.rb +6 -4
  184. data/lib/active_support/logger_thread_safe_level.rb +7 -5
  185. data/lib/active_support/message_encryptor.rb +168 -53
  186. data/lib/active_support/message_verifier.rb +150 -17
  187. data/lib/active_support/messages/metadata.rb +71 -0
  188. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  189. data/lib/active_support/messages/rotator.rb +56 -0
  190. data/lib/active_support/multibyte/chars.rb +36 -23
  191. data/lib/active_support/multibyte/unicode.rb +100 -96
  192. data/lib/active_support/multibyte.rb +4 -2
  193. data/lib/active_support/notifications/fanout.rb +11 -9
  194. data/lib/active_support/notifications/instrumenter.rb +27 -7
  195. data/lib/active_support/notifications.rb +11 -7
  196. data/lib/active_support/number_helper/number_converter.rb +13 -11
  197. data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
  198. data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
  199. data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
  200. data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
  201. data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
  202. data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
  203. data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
  204. data/lib/active_support/number_helper/rounding_helper.rb +66 -0
  205. data/lib/active_support/number_helper.rb +94 -68
  206. data/lib/active_support/option_merger.rb +3 -1
  207. data/lib/active_support/ordered_hash.rb +6 -4
  208. data/lib/active_support/ordered_options.rb +23 -5
  209. data/lib/active_support/per_thread_registry.rb +9 -4
  210. data/lib/active_support/proxy_object.rb +2 -0
  211. data/lib/active_support/rails.rb +16 -8
  212. data/lib/active_support/railtie.rb +43 -9
  213. data/lib/active_support/reloader.rb +131 -0
  214. data/lib/active_support/rescuable.rb +108 -53
  215. data/lib/active_support/security_utils.rb +15 -11
  216. data/lib/active_support/string_inquirer.rb +11 -3
  217. data/lib/active_support/subscriber.rb +21 -16
  218. data/lib/active_support/tagged_logging.rb +14 -11
  219. data/lib/active_support/test_case.rb +19 -47
  220. data/lib/active_support/testing/assertions.rb +137 -20
  221. data/lib/active_support/testing/autorun.rb +4 -2
  222. data/lib/active_support/testing/constant_lookup.rb +2 -1
  223. data/lib/active_support/testing/declarative.rb +3 -1
  224. data/lib/active_support/testing/deprecation.rb +14 -10
  225. data/lib/active_support/testing/file_fixtures.rb +36 -0
  226. data/lib/active_support/testing/isolation.rb +34 -25
  227. data/lib/active_support/testing/method_call_assertions.rb +43 -0
  228. data/lib/active_support/testing/setup_and_teardown.rb +13 -8
  229. data/lib/active_support/testing/stream.rb +44 -0
  230. data/lib/active_support/testing/tagged_logging.rb +3 -1
  231. data/lib/active_support/testing/time_helpers.rb +81 -15
  232. data/lib/active_support/time.rb +14 -12
  233. data/lib/active_support/time_with_zone.rb +169 -39
  234. data/lib/active_support/values/time_zone.rb +196 -61
  235. data/lib/active_support/values/unicode_tables.dat +0 -0
  236. data/lib/active_support/version.rb +3 -1
  237. data/lib/active_support/xml_mini/jdom.rb +116 -114
  238. data/lib/active_support/xml_mini/libxml.rb +16 -13
  239. data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
  240. data/lib/active_support/xml_mini/nokogiri.rb +14 -12
  241. data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
  242. data/lib/active_support/xml_mini/rexml.rb +11 -9
  243. data/lib/active_support/xml_mini.rb +37 -37
  244. data/lib/active_support.rb +12 -11
  245. metadata +57 -27
  246. data/lib/active_support/concurrency/latch.rb +0 -27
  247. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  248. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  249. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  250. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  251. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
  252. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  253. data/lib/active_support/core_ext/object/itself.rb +0 -15
  254. data/lib/active_support/core_ext/struct.rb +0 -6
  255. data/lib/active_support/core_ext/thread.rb +0 -86
  256. data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -1,8 +1,10 @@
1
- require 'active_support/core_ext/big_decimal/conversions'
2
- require 'active_support/core_ext/object/blank'
3
- require 'active_support/core_ext/hash/keys'
4
- require 'active_support/i18n'
5
- require 'active_support/core_ext/class/attribute'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/big_decimal/conversions"
4
+ require "active_support/core_ext/object/blank"
5
+ require "active_support/core_ext/hash/keys"
6
+ require "active_support/i18n"
7
+ require "active_support/core_ext/class/attribute"
6
8
 
7
9
  module ActiveSupport
8
10
  module NumberHelper
@@ -139,17 +141,17 @@ module ActiveSupport
139
141
  @options ||= format_options.merge(opts)
140
142
  end
141
143
 
142
- def format_options #:nodoc:
144
+ def format_options
143
145
  default_format_options.merge!(i18n_format_options)
144
146
  end
145
147
 
146
- def default_format_options #:nodoc:
148
+ def default_format_options
147
149
  options = DEFAULTS[:format].dup
148
150
  options.merge!(DEFAULTS[namespace][:format]) if namespace
149
151
  options
150
152
  end
151
153
 
152
- def i18n_format_options #:nodoc:
154
+ def i18n_format_options
153
155
  locale = opts[:locale]
154
156
  options = I18n.translate(:'number.format', locale: locale, default: {}).dup
155
157
 
@@ -160,7 +162,7 @@ module ActiveSupport
160
162
  options
161
163
  end
162
164
 
163
- def translate_number_value_with_default(key, i18n_options = {}) #:nodoc:
165
+ def translate_number_value_with_default(key, i18n_options = {})
164
166
  I18n.translate(key, { default: default_value(key), scope: :number }.merge!(i18n_options))
165
167
  end
166
168
 
@@ -169,10 +171,10 @@ module ActiveSupport
169
171
  end
170
172
 
171
173
  def default_value(key)
172
- key.split('.').reduce(DEFAULTS) { |defaults, k| defaults[k.to_sym] }
174
+ key.split(".").reduce(DEFAULTS) { |defaults, k| defaults[k.to_sym] }
173
175
  end
174
176
 
175
- def valid_float? #:nodoc:
177
+ def valid_float?
176
178
  Float(number)
177
179
  rescue ArgumentError, TypeError
178
180
  false
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/numeric/inquiry"
4
+
1
5
  module ActiveSupport
2
6
  module NumberHelper
3
7
  class NumberToCurrencyConverter < NumberConverter # :nodoc:
@@ -7,36 +11,32 @@ module ActiveSupport
7
11
  number = self.number.to_s.strip
8
12
  format = options[:format]
9
13
 
10
- if is_negative?(number)
14
+ if number.to_f.negative?
11
15
  format = options[:negative_format]
12
16
  number = absolute_value(number)
13
17
  end
14
18
 
15
19
  rounded_number = NumberToRoundedConverter.convert(number, options)
16
- format.gsub(/%n/, rounded_number).gsub(/%u/, options[:unit])
20
+ format.gsub("%n".freeze, rounded_number).gsub("%u".freeze, options[:unit])
17
21
  end
18
22
 
19
23
  private
20
24
 
21
- def is_negative?(number)
22
- number.to_f.phase != 0
23
- end
24
-
25
25
  def absolute_value(number)
26
- number.respond_to?("abs") ? number.abs : number.sub(/\A-/, '')
26
+ number.respond_to?(:abs) ? number.abs : number.sub(/\A-/, "")
27
27
  end
28
28
 
29
29
  def options
30
30
  @options ||= begin
31
31
  defaults = default_format_options.merge(i18n_opts)
32
- # Override negative format if format options is given
32
+ # Override negative format if format options are given
33
33
  defaults[:negative_format] = "-#{opts[:format]}" if opts[:format]
34
34
  defaults.merge!(opts)
35
35
  end
36
36
  end
37
37
 
38
38
  def i18n_opts
39
- # Set International negative format if not exists
39
+ # Set International negative format if it does not exist
40
40
  i18n = i18n_format_options
41
41
  i18n[:negative_format] ||= "-#{i18n[:format]}" if i18n[:format]
42
42
  i18n
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module NumberHelper
3
5
  class NumberToDelimitedConverter < NumberConverter #:nodoc:
4
6
  self.validate_float = true
5
7
 
6
- DELIMITED_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/
8
+ DEFAULT_DELIMITER_REGEX = /(\d)(?=(\d\d\d)+(?!\d))/
7
9
 
8
10
  def convert
9
11
  parts.join(options[:separator])
@@ -12,12 +14,16 @@ module ActiveSupport
12
14
  private
13
15
 
14
16
  def parts
15
- left, right = number.to_s.split('.')
16
- left.gsub!(DELIMITED_REGEX) do |digit_to_delimit|
17
+ left, right = number.to_s.split(".".freeze)
18
+ left.gsub!(delimiter_pattern) do |digit_to_delimit|
17
19
  "#{digit_to_delimit}#{options[:delimiter]}"
18
20
  end
19
21
  [left, right].compact
20
22
  end
23
+
24
+ def delimiter_pattern
25
+ options.fetch(:delimiter_pattern, DEFAULT_DELIMITER_REGEX)
26
+ end
21
27
  end
22
28
  end
23
29
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module NumberHelper
3
5
  class NumberToHumanConverter < NumberConverter # :nodoc:
@@ -9,6 +11,7 @@ module ActiveSupport
9
11
  self.validate_float = true
10
12
 
11
13
  def convert # :nodoc:
14
+ @number = RoundingHelper.new(options).round(number)
12
15
  @number = Float(number)
13
16
 
14
17
  # for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
@@ -18,27 +21,26 @@ module ActiveSupport
18
21
 
19
22
  units = opts[:units]
20
23
  exponent = calculate_exponent(units)
21
- @number = number / (10 ** exponent)
22
-
23
- unit = determine_unit(units, exponent)
24
+ @number = number / (10**exponent)
24
25
 
25
26
  rounded_number = NumberToRoundedConverter.convert(number, options)
26
- format.gsub(/%n/, rounded_number).gsub(/%u/, unit).strip
27
+ unit = determine_unit(units, exponent)
28
+ format.gsub("%n".freeze, rounded_number).gsub("%u".freeze, unit).strip
27
29
  end
28
30
 
29
31
  private
30
32
 
31
33
  def format
32
- options[:format] || translate_in_locale('human.decimal_units.format')
34
+ options[:format] || translate_in_locale("human.decimal_units.format")
33
35
  end
34
36
 
35
37
  def determine_unit(units, exponent)
36
38
  exp = DECIMAL_UNITS[exponent]
37
39
  case units
38
40
  when Hash
39
- units[exp] || ''
41
+ units[exp] || ""
40
42
  when String, Symbol
41
- I18n.translate("#{units}.#{exp}", :locale => options[:locale], :count => number.to_i)
43
+ I18n.translate("#{units}.#{exp}", locale: options[:locale], count: number.to_i)
42
44
  else
43
45
  translate_in_locale("human.decimal_units.units.#{exp}", count: number.to_i)
44
46
  end
@@ -54,12 +56,12 @@ module ActiveSupport
54
56
  when Hash
55
57
  units
56
58
  when String, Symbol
57
- I18n.translate(units.to_s, :locale => options[:locale], :raise => true)
59
+ I18n.translate(units.to_s, locale: options[:locale], raise: true)
58
60
  when nil
59
61
  translate_in_locale("human.decimal_units.units", raise: true)
60
62
  else
61
63
  raise ArgumentError, ":units must be a Hash or String translation scope."
62
- end.keys.map { |e_name| INVERTED_DECIMAL_UNITS[e_name] }.sort_by { |e| -e }
64
+ end.keys.map { |e_name| INVERTED_DECIMAL_UNITS[e_name] }.sort_by(&:-@)
63
65
  end
64
66
  end
65
67
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module NumberHelper
3
5
  class NumberToHumanSizeConverter < NumberConverter #:nodoc:
4
- STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb]
6
+ STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb, :pb, :eb]
5
7
 
6
8
  self.namespace = :human
7
9
  self.validate_float = true
@@ -17,24 +19,24 @@ module ActiveSupport
17
19
  if smaller_than_base?
18
20
  number_to_format = number.to_i.to_s
19
21
  else
20
- human_size = number / (base ** exponent)
22
+ human_size = number / (base**exponent)
21
23
  number_to_format = NumberToRoundedConverter.convert(human_size, options)
22
24
  end
23
- conversion_format.gsub(/%n/, number_to_format).gsub(/%u/, unit)
25
+ conversion_format.gsub("%n".freeze, number_to_format).gsub("%u".freeze, unit)
24
26
  end
25
27
 
26
28
  private
27
29
 
28
30
  def conversion_format
29
- translate_number_value_with_default('human.storage_units.format', :locale => options[:locale], :raise => true)
31
+ translate_number_value_with_default("human.storage_units.format", locale: options[:locale], raise: true)
30
32
  end
31
33
 
32
34
  def unit
33
- translate_number_value_with_default(storage_unit_key, :locale => options[:locale], :count => number.to_i, :raise => true)
35
+ translate_number_value_with_default(storage_unit_key, locale: options[:locale], count: number.to_i, raise: true)
34
36
  end
35
37
 
36
38
  def storage_unit_key
37
- key_end = smaller_than_base? ? 'byte' : STORAGE_UNITS[exponent]
39
+ key_end = smaller_than_base? ? "byte" : STORAGE_UNITS[exponent]
38
40
  "human.storage_units.units.#{key_end}"
39
41
  end
40
42
 
@@ -50,9 +52,8 @@ module ActiveSupport
50
52
  end
51
53
 
52
54
  def base
53
- opts[:prefix] == :si ? 1000 : 1024
55
+ 1024
54
56
  end
55
57
  end
56
58
  end
57
59
  end
58
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module NumberHelper
3
5
  class NumberToPercentageConverter < NumberConverter # :nodoc:
@@ -5,7 +7,7 @@ module ActiveSupport
5
7
 
6
8
  def convert
7
9
  rounded_number = NumberToRoundedConverter.convert(number, options)
8
- options[:format].gsub(/%n/, rounded_number)
10
+ options[:format].gsub("%n".freeze, rounded_number)
9
11
  end
10
12
  end
11
13
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module NumberHelper
3
5
  class NumberToPhoneConverter < NumberConverter #:nodoc:
4
6
  def convert
5
- str = country_code(opts[:country_code])
7
+ str = country_code(opts[:country_code]).dup
6
8
  str << convert_to_phone_number(number.to_s.strip)
7
9
  str << phone_ext(opts[:extension])
8
10
  end
@@ -18,12 +20,16 @@ module ActiveSupport
18
20
  end
19
21
 
20
22
  def convert_with_area_code(number)
21
- number.gsub!(/(\d{1,3})(\d{3})(\d{4}$)/,"(\\1) \\2#{delimiter}\\3")
23
+ default_pattern = /(\d{1,3})(\d{3})(\d{4}$)/
24
+ number.gsub!(regexp_pattern(default_pattern),
25
+ "(\\1) \\2#{delimiter}\\3")
22
26
  number
23
27
  end
24
28
 
25
29
  def convert_without_area_code(number)
26
- number.gsub!(/(\d{0,3})(\d{3})(\d{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3")
30
+ default_pattern = /(\d{0,3})(\d{3})(\d{4})$/
31
+ number.gsub!(regexp_pattern(default_pattern),
32
+ "\\1#{delimiter}\\2#{delimiter}\\3")
27
33
  number.slice!(0, 1) if start_with_delimiter?(number)
28
34
  number
29
35
  end
@@ -43,7 +49,10 @@ module ActiveSupport
43
49
  def phone_ext(ext)
44
50
  ext.blank? ? "" : " x #{ext}"
45
51
  end
52
+
53
+ def regexp_pattern(default_pattern)
54
+ opts.fetch :pattern, default_pattern
55
+ end
46
56
  end
47
57
  end
48
58
  end
49
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  module NumberHelper
3
5
  class NumberToRoundedConverter < NumberConverter # :nodoc:
@@ -5,63 +7,36 @@ module ActiveSupport
5
7
  self.validate_float = true
6
8
 
7
9
  def convert
8
- precision = options.delete :precision
9
- significant = options.delete :significant
10
-
11
- case number
12
- when Float, String
13
- @number = BigDecimal(number.to_s)
14
- when Rational
15
- @number = BigDecimal(number, digit_count(number.to_i) + precision)
16
- else
17
- @number = number.to_d
18
- end
10
+ helper = RoundingHelper.new(options)
11
+ rounded_number = helper.round(number)
12
+
13
+ if precision = options[:precision]
14
+ if options[:significant] && precision > 0
15
+ digits = helper.digit_count(rounded_number)
16
+ precision -= digits
17
+ precision = 0 if precision < 0 # don't let it be negative
18
+ end
19
19
 
20
- if significant && precision > 0
21
- digits, rounded_number = digits_and_rounded_number(precision)
22
- precision -= digits
23
- precision = 0 if precision < 0 # don't let it be negative
20
+ formatted_string =
21
+ if BigDecimal === rounded_number && rounded_number.finite?
22
+ s = rounded_number.to_s("F")
23
+ s << "0".freeze * precision
24
+ a, b = s.split(".".freeze, 2)
25
+ a << ".".freeze
26
+ a << b[0, precision]
27
+ else
28
+ "%00.#{precision}f" % rounded_number
29
+ end
24
30
  else
25
- rounded_number = number.round(precision)
26
- rounded_number = rounded_number.to_i if precision == 0 && rounded_number.finite?
27
- rounded_number = rounded_number.abs if rounded_number.zero? # prevent showing negative zeros
31
+ formatted_string = rounded_number
28
32
  end
29
33
 
30
- formatted_string =
31
- if BigDecimal === rounded_number && rounded_number.finite?
32
- s = rounded_number.to_s('F') + '0'*precision
33
- a, b = s.split('.', 2)
34
- a + '.' + b[0, precision]
35
- else
36
- "%00.#{precision}f" % rounded_number
37
- end
38
-
39
34
  delimited_number = NumberToDelimitedConverter.convert(formatted_string, options)
40
35
  format_number(delimited_number)
41
36
  end
42
37
 
43
38
  private
44
39
 
45
- def digits_and_rounded_number(precision)
46
- if zero?
47
- [1, 0]
48
- else
49
- digits = digit_count(number)
50
- multiplier = 10 ** (digits - precision)
51
- rounded_number = calculate_rounded_number(multiplier)
52
- digits = digit_count(rounded_number) # After rounding, the number of digits may have changed
53
- [digits, rounded_number]
54
- end
55
- end
56
-
57
- def calculate_rounded_number(multiplier)
58
- (number / BigDecimal.new(multiplier.to_f.to_s)).round * multiplier
59
- end
60
-
61
- def digit_count(number)
62
- number.zero? ? 1 : (Math.log10(absolute_number(number)) + 1).floor
63
- end
64
-
65
40
  def strip_insignificant_zeros
66
41
  options[:strip_insignificant_zeros]
67
42
  end
@@ -69,19 +44,11 @@ module ActiveSupport
69
44
  def format_number(number)
70
45
  if strip_insignificant_zeros
71
46
  escaped_separator = Regexp.escape(options[:separator])
72
- number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
47
+ number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, "")
73
48
  else
74
49
  number
75
50
  end
76
51
  end
77
-
78
- def absolute_number(number)
79
- number.respond_to?(:abs) ? number.abs : number.to_d.abs
80
- end
81
-
82
- def zero?
83
- number.respond_to?(:zero?) ? number.zero? : number.to_d.zero?
84
- end
85
52
  end
86
53
  end
87
54
  end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module NumberHelper
5
+ class RoundingHelper # :nodoc:
6
+ attr_reader :options
7
+
8
+ def initialize(options)
9
+ @options = options
10
+ end
11
+
12
+ def round(number)
13
+ return number unless precision
14
+ number = convert_to_decimal(number)
15
+ if significant && precision > 0
16
+ round_significant(number)
17
+ else
18
+ round_without_significant(number)
19
+ end
20
+ end
21
+
22
+ def digit_count(number)
23
+ return 1 if number.zero?
24
+ (Math.log10(absolute_number(number)) + 1).floor
25
+ end
26
+
27
+ private
28
+ def round_without_significant(number)
29
+ number = number.round(precision)
30
+ number = number.to_i if precision == 0 && number.finite?
31
+ number = number.abs if number.zero? # prevent showing negative zeros
32
+ number
33
+ end
34
+
35
+ def round_significant(number)
36
+ return 0 if number.zero?
37
+ digits = digit_count(number)
38
+ multiplier = 10**(digits - precision)
39
+ (number / BigDecimal(multiplier.to_f.to_s)).round * multiplier
40
+ end
41
+
42
+ def convert_to_decimal(number)
43
+ case number
44
+ when Float, String
45
+ BigDecimal(number.to_s)
46
+ when Rational
47
+ BigDecimal(number, digit_count(number.to_i) + precision)
48
+ else
49
+ number.to_d
50
+ end
51
+ end
52
+
53
+ def precision
54
+ options[:precision]
55
+ end
56
+
57
+ def significant
58
+ options[:significant]
59
+ end
60
+
61
+ def absolute_number(number)
62
+ number.respond_to?(:abs) ? number.abs : number.to_d.abs
63
+ end
64
+ end
65
+ end
66
+ end