activesupport 4.2.0 → 5.2.0

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 (254) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +366 -232
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +4 -5
  5. data/lib/active_support.rb +17 -7
  6. data/lib/active_support/all.rb +5 -3
  7. data/lib/active_support/array_inquirer.rb +48 -0
  8. data/lib/active_support/backtrace_cleaner.rb +7 -5
  9. data/lib/active_support/benchmarkable.rb +6 -4
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache.rb +271 -177
  12. data/lib/active_support/cache/file_store.rb +41 -35
  13. data/lib/active_support/cache/mem_cache_store.rb +97 -88
  14. data/lib/active_support/cache/memory_store.rb +27 -30
  15. data/lib/active_support/cache/null_store.rb +7 -8
  16. data/lib/active_support/cache/redis_cache_store.rb +454 -0
  17. data/lib/active_support/cache/strategy/local_cache.rb +67 -34
  18. data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
  19. data/lib/active_support/callbacks.rb +654 -560
  20. data/lib/active_support/concern.rb +5 -3
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  22. data/lib/active_support/concurrency/share_lock.rb +227 -0
  23. data/lib/active_support/configurable.rb +8 -5
  24. data/lib/active_support/core_ext.rb +3 -1
  25. data/lib/active_support/core_ext/array.rb +9 -6
  26. data/lib/active_support/core_ext/array/access.rb +29 -1
  27. data/lib/active_support/core_ext/array/conversions.rb +22 -18
  28. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +11 -18
  30. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  31. data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
  32. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  33. data/lib/active_support/core_ext/benchmark.rb +3 -1
  34. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  35. data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
  36. data/lib/active_support/core_ext/class.rb +4 -3
  37. data/lib/active_support/core_ext/class/attribute.rb +41 -22
  38. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
  39. data/lib/active_support/core_ext/class/subclasses.rb +20 -8
  40. data/lib/active_support/core_ext/date.rb +6 -4
  41. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  42. data/lib/active_support/core_ext/date/blank.rb +14 -0
  43. data/lib/active_support/core_ext/date/calculations.rb +11 -9
  44. data/lib/active_support/core_ext/date/conversions.rb +31 -23
  45. data/lib/active_support/core_ext/date/zones.rb +4 -2
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +179 -56
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +16 -0
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
  49. data/lib/active_support/core_ext/date_time.rb +7 -4
  50. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  51. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  52. data/lib/active_support/core_ext/date_time/calculations.rb +58 -20
  53. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  54. data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
  55. data/lib/active_support/core_ext/digest/uuid.rb +7 -5
  56. data/lib/active_support/core_ext/enumerable.rb +107 -28
  57. data/lib/active_support/core_ext/file.rb +3 -1
  58. data/lib/active_support/core_ext/file/atomic.rb +38 -31
  59. data/lib/active_support/core_ext/hash.rb +11 -9
  60. data/lib/active_support/core_ext/hash/compact.rb +24 -15
  61. data/lib/active_support/core_ext/hash/conversions.rb +63 -43
  62. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  63. data/lib/active_support/core_ext/hash/except.rb +11 -8
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
  65. data/lib/active_support/core_ext/hash/keys.rb +33 -27
  66. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  67. data/lib/active_support/core_ext/hash/slice.rb +8 -8
  68. data/lib/active_support/core_ext/hash/transform_values.rb +16 -7
  69. data/lib/active_support/core_ext/integer.rb +5 -3
  70. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  71. data/lib/active_support/core_ext/integer/multiple.rb +2 -0
  72. data/lib/active_support/core_ext/integer/time.rb +11 -33
  73. data/lib/active_support/core_ext/kernel.rb +6 -5
  74. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
  75. data/lib/active_support/core_ext/kernel/concern.rb +5 -1
  76. data/lib/active_support/core_ext/kernel/reporting.rb +4 -83
  77. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  78. data/lib/active_support/core_ext/load_error.rb +3 -22
  79. data/lib/active_support/core_ext/marshal.rb +13 -10
  80. data/lib/active_support/core_ext/module.rb +14 -11
  81. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  82. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  83. data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
  84. data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
  85. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
  86. data/lib/active_support/core_ext/module/concerning.rb +11 -12
  87. data/lib/active_support/core_ext/module/delegation.rb +121 -39
  88. data/lib/active_support/core_ext/module/deprecation.rb +4 -2
  89. data/lib/active_support/core_ext/module/introspection.rb +9 -9
  90. data/lib/active_support/core_ext/module/reachable.rb +5 -2
  91. data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  93. data/lib/active_support/core_ext/name_error.rb +22 -2
  94. data/lib/active_support/core_ext/numeric.rb +6 -3
  95. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +79 -74
  97. data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +35 -38
  99. data/lib/active_support/core_ext/object.rb +14 -13
  100. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  101. data/lib/active_support/core_ext/object/blank.rb +29 -4
  102. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  103. data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
  104. data/lib/active_support/core_ext/object/duplicable.rb +98 -45
  105. data/lib/active_support/core_ext/object/inclusion.rb +5 -3
  106. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  107. data/lib/active_support/core_ext/object/json.rb +49 -19
  108. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  109. data/lib/active_support/core_ext/object/to_query.rb +6 -4
  110. data/lib/active_support/core_ext/object/try.rb +70 -22
  111. data/lib/active_support/core_ext/object/with_options.rb +16 -3
  112. data/lib/active_support/core_ext/range.rb +7 -4
  113. data/lib/active_support/core_ext/range/conversions.rb +27 -7
  114. data/lib/active_support/core_ext/range/each.rb +19 -17
  115. data/lib/active_support/core_ext/range/include_range.rb +21 -19
  116. data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
  117. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  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.rb +15 -13
  121. data/lib/active_support/core_ext/string/access.rb +9 -7
  122. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  123. data/lib/active_support/core_ext/string/conversions.rb +8 -5
  124. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  125. data/lib/active_support/core_ext/string/filters.rb +10 -8
  126. data/lib/active_support/core_ext/string/indent.rb +6 -4
  127. data/lib/active_support/core_ext/string/inflections.rb +61 -24
  128. data/lib/active_support/core_ext/string/inquiry.rb +3 -1
  129. data/lib/active_support/core_ext/string/multibyte.rb +15 -7
  130. data/lib/active_support/core_ext/string/output_safety.rb +35 -35
  131. data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
  132. data/lib/active_support/core_ext/string/strip.rb +4 -5
  133. data/lib/active_support/core_ext/string/zones.rb +4 -2
  134. data/lib/active_support/core_ext/time.rb +7 -5
  135. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  136. data/lib/active_support/core_ext/time/calculations.rb +101 -51
  137. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  138. data/lib/active_support/core_ext/time/conversions.rb +20 -13
  139. data/lib/active_support/core_ext/time/zones.rb +41 -7
  140. data/lib/active_support/core_ext/uri.rb +5 -4
  141. data/lib/active_support/current_attributes.rb +195 -0
  142. data/lib/active_support/dependencies.rb +143 -160
  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/deprecation.rb +12 -9
  146. data/lib/active_support/deprecation/behaviors.rb +41 -12
  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 +54 -21
  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/descendants_tracker.rb +2 -0
  153. data/lib/active_support/digest.rb +20 -0
  154. data/lib/active_support/duration.rb +326 -30
  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/encrypted_configuration.rb +49 -0
  158. data/lib/active_support/encrypted_file.rb +99 -0
  159. data/lib/active_support/evented_file_update_checker.rb +205 -0
  160. data/lib/active_support/execution_wrapper.rb +128 -0
  161. data/lib/active_support/executor.rb +8 -0
  162. data/lib/active_support/file_update_checker.rb +63 -37
  163. data/lib/active_support/gem_version.rb +4 -2
  164. data/lib/active_support/gzip.rb +7 -5
  165. data/lib/active_support/hash_with_indifferent_access.rb +130 -30
  166. data/lib/active_support/i18n.rb +8 -6
  167. data/lib/active_support/i18n_railtie.rb +34 -14
  168. data/lib/active_support/inflections.rb +13 -11
  169. data/lib/active_support/inflector.rb +7 -5
  170. data/lib/active_support/inflector/inflections.rb +61 -12
  171. data/lib/active_support/inflector/methods.rb +161 -136
  172. data/lib/active_support/inflector/transliterate.rb +48 -27
  173. data/lib/active_support/json.rb +4 -2
  174. data/lib/active_support/json/decoding.rb +16 -13
  175. data/lib/active_support/json/encoding.rb +15 -57
  176. data/lib/active_support/key_generator.rb +25 -25
  177. data/lib/active_support/lazy_load_hooks.rb +50 -20
  178. data/lib/active_support/locale/en.yml +2 -0
  179. data/lib/active_support/log_subscriber.rb +13 -10
  180. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  181. data/lib/active_support/logger.rb +54 -3
  182. data/lib/active_support/logger_silence.rb +12 -7
  183. data/lib/active_support/logger_thread_safe_level.rb +33 -0
  184. data/lib/active_support/message_encryptor.rb +173 -51
  185. data/lib/active_support/message_verifier.rb +150 -17
  186. data/lib/active_support/messages/metadata.rb +71 -0
  187. data/lib/active_support/messages/rotation_configuration.rb +22 -0
  188. data/lib/active_support/messages/rotator.rb +56 -0
  189. data/lib/active_support/multibyte.rb +4 -2
  190. data/lib/active_support/multibyte/chars.rb +37 -24
  191. data/lib/active_support/multibyte/unicode.rb +100 -96
  192. data/lib/active_support/notifications.rb +11 -7
  193. data/lib/active_support/notifications/fanout.rb +10 -8
  194. data/lib/active_support/notifications/instrumenter.rb +27 -7
  195. data/lib/active_support/number_helper.rb +94 -68
  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/option_merger.rb +3 -1
  206. data/lib/active_support/ordered_hash.rb +6 -4
  207. data/lib/active_support/ordered_options.rb +22 -4
  208. data/lib/active_support/per_thread_registry.rb +13 -6
  209. data/lib/active_support/proxy_object.rb +2 -0
  210. data/lib/active_support/rails.rb +16 -8
  211. data/lib/active_support/railtie.rb +43 -9
  212. data/lib/active_support/reloader.rb +131 -0
  213. data/lib/active_support/rescuable.rb +108 -53
  214. data/lib/active_support/security_utils.rb +17 -6
  215. data/lib/active_support/string_inquirer.rb +11 -3
  216. data/lib/active_support/subscriber.rb +15 -14
  217. data/lib/active_support/tagged_logging.rb +14 -11
  218. data/lib/active_support/test_case.rb +18 -46
  219. data/lib/active_support/testing/assertions.rb +137 -20
  220. data/lib/active_support/testing/autorun.rb +4 -2
  221. data/lib/active_support/testing/constant_lookup.rb +2 -1
  222. data/lib/active_support/testing/declarative.rb +3 -1
  223. data/lib/active_support/testing/deprecation.rb +14 -10
  224. data/lib/active_support/testing/file_fixtures.rb +36 -0
  225. data/lib/active_support/testing/isolation.rb +34 -25
  226. data/lib/active_support/testing/method_call_assertions.rb +43 -0
  227. data/lib/active_support/testing/setup_and_teardown.rb +12 -3
  228. data/lib/active_support/testing/stream.rb +44 -0
  229. data/lib/active_support/testing/tagged_logging.rb +3 -1
  230. data/lib/active_support/testing/time_helpers.rb +96 -27
  231. data/lib/active_support/time.rb +14 -12
  232. data/lib/active_support/time_with_zone.rb +195 -53
  233. data/lib/active_support/values/time_zone.rb +200 -61
  234. data/lib/active_support/values/unicode_tables.dat +0 -0
  235. data/lib/active_support/version.rb +3 -1
  236. data/lib/active_support/xml_mini.rb +69 -51
  237. data/lib/active_support/xml_mini/jdom.rb +116 -113
  238. data/lib/active_support/xml_mini/libxml.rb +17 -16
  239. data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
  240. data/lib/active_support/xml_mini/nokogiri.rb +15 -15
  241. data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
  242. data/lib/active_support/xml_mini/rexml.rb +17 -16
  243. metadata +55 -43
  244. data/lib/active_support/concurrency/latch.rb +0 -27
  245. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -14
  246. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  247. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  248. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  249. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -11
  250. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  251. data/lib/active_support/core_ext/object/itself.rb +0 -15
  252. data/lib/active_support/core_ext/struct.rb +0 -6
  253. data/lib/active_support/core_ext/thread.rb +0 -86
  254. data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -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
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
@@ -1,4 +1,6 @@
1
- require 'active_support/core_ext/hash/deep_merge'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/deep_merge"
2
4
 
3
5
  module ActiveSupport
4
6
  class OptionMerger #:nodoc:
@@ -1,11 +1,13 @@
1
- require 'yaml'
1
+ # frozen_string_literal: true
2
+
3
+ require "yaml"
2
4
 
3
5
  YAML.add_builtin_type("omap") do |type, val|
4
- ActiveSupport::OrderedHash[val.map{ |v| v.to_a.first }]
6
+ ActiveSupport::OrderedHash[val.map { |v| v.to_a.first }]
5
7
  end
6
8
 
7
9
  module ActiveSupport
8
- # <tt>ActiveSupport::OrderedHash</tt> implements a hash that preserves
10
+ # DEPRECATED: <tt>ActiveSupport::OrderedHash</tt> implements a hash that preserves
9
11
  # insertion order.
10
12
  #
11
13
  # oh = ActiveSupport::OrderedHash.new
@@ -25,7 +27,7 @@ module ActiveSupport
25
27
  end
26
28
 
27
29
  def encode_with(coder)
28
- coder.represent_seq '!omap', map { |k,v| { k => v } }
30
+ coder.represent_seq "!omap", map { |k, v| { k => v } }
29
31
  end
30
32
 
31
33
  def select(*args, &block)
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/object/blank"
4
+
1
5
  module ActiveSupport
2
6
  # Usually key value pairs are handled something like this:
3
7
  #
@@ -6,6 +10,7 @@ module ActiveSupport
6
10
  # h[:girl] = 'Mary'
7
11
  # h[:boy] # => 'John'
8
12
  # h[:girl] # => 'Mary'
13
+ # h[:dog] # => nil
9
14
  #
10
15
  # Using +OrderedOptions+, the above code could be reduced to:
11
16
  #
@@ -14,6 +19,13 @@ module ActiveSupport
14
19
  # h.girl = 'Mary'
15
20
  # h.boy # => 'John'
16
21
  # h.girl # => 'Mary'
22
+ # h.dog # => nil
23
+ #
24
+ # To raise an exception when the value is blank, append a
25
+ # bang to the key name, like:
26
+ #
27
+ # h.dog! # => raises KeyError: :dog is blank
28
+ #
17
29
  class OrderedOptions < Hash
18
30
  alias_method :_get, :[] # preserve the original #[] method
19
31
  protected :_get # make it protected
@@ -28,10 +40,16 @@ module ActiveSupport
28
40
 
29
41
  def method_missing(name, *args)
30
42
  name_string = name.to_s
31
- if name_string.chomp!('=')
43
+ if name_string.chomp!("=")
32
44
  self[name_string] = args.first
33
45
  else
34
- self[name]
46
+ bangs = name_string.chomp!("!")
47
+
48
+ if bangs
49
+ self[name_string].presence || raise(KeyError.new(":#{name_string} is blank"))
50
+ else
51
+ self[name_string]
52
+ end
35
53
  end
36
54
  end
37
55
 
@@ -52,9 +70,9 @@ module ActiveSupport
52
70
  def initialize(parent = nil)
53
71
  if parent.kind_of?(OrderedOptions)
54
72
  # use the faster _get when dealing with OrderedOptions
55
- super() { |h,k| parent._get(k) }
73
+ super() { |h, k| parent._get(k) }
56
74
  elsif parent
57
- super() { |h,k| parent[k] }
75
+ super() { |h, k| parent[k] }
58
76
  else
59
77
  super()
60
78
  end
@@ -1,4 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/delegation"
4
+
1
5
  module ActiveSupport
6
+ # NOTE: This approach has been deprecated for end-user code in favor of {thread_mattr_accessor}[rdoc-ref:Module#thread_mattr_accessor] and friends.
7
+ # Please use that approach instead.
8
+ #
2
9
  # This module is used to encapsulate access to thread local variables.
3
10
  #
4
11
  # Instead of polluting the thread locals namespace:
@@ -33,19 +40,19 @@ module ActiveSupport
33
40
  # If the class has an initializer, it must accept no arguments.
34
41
  module PerThreadRegistry
35
42
  def self.extended(object)
36
- object.instance_variable_set '@per_thread_registry_key', object.name.freeze
43
+ object.instance_variable_set "@per_thread_registry_key", object.name.freeze
37
44
  end
38
45
 
39
46
  def instance
40
47
  Thread.current[@per_thread_registry_key] ||= new
41
48
  end
42
49
 
43
- protected
44
- def method_missing(name, *args, &block) # :nodoc:
50
+ private
51
+ def method_missing(name, *args, &block)
45
52
  # Caches the method definition as a singleton method of the receiver.
46
- define_singleton_method(name) do |*a, &b|
47
- instance.public_send(name, *a, &b)
48
- end
53
+ #
54
+ # By letting #delegate handle it, we avoid an enclosure that'll capture args.
55
+ singleton_class.delegate name, to: :instance
49
56
 
50
57
  send(name, *args, &block)
51
58
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveSupport
2
4
  # A class with no predefined methods that behaves similarly to Builder's
3
5
  # BlankSlate. Used for proxy classes.
@@ -1,27 +1,35 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This is private interface.
2
4
  #
3
5
  # Rails components cherry pick from Active Support as needed, but there are a
4
- # few features that are used for sure some way or another and it is not worth
5
- # to put individual requires absolutely everywhere. Think blank? for example.
6
+ # few features that are used for sure in some way or another and it is not worth
7
+ # putting individual requires absolutely everywhere. Think blank? for example.
6
8
  #
7
9
  # This file is loaded by every Rails component except Active Support itself,
8
10
  # but it does not belong to the Rails public interface. It is internal to
9
11
  # Rails and can change anytime.
10
12
 
11
13
  # Defines Object#blank? and Object#present?.
12
- require 'active_support/core_ext/object/blank'
14
+ require "active_support/core_ext/object/blank"
13
15
 
14
16
  # Rails own autoload, eager_load, etc.
15
- require 'active_support/dependencies/autoload'
17
+ require "active_support/dependencies/autoload"
16
18
 
17
19
  # Support for ClassMethods and the included macro.
18
- require 'active_support/concern'
20
+ require "active_support/concern"
19
21
 
20
22
  # Defines Class#class_attribute.
21
- require 'active_support/core_ext/class/attribute'
23
+ require "active_support/core_ext/class/attribute"
22
24
 
23
25
  # Defines Module#delegate.
24
- require 'active_support/core_ext/module/delegation'
26
+ require "active_support/core_ext/module/delegation"
25
27
 
26
28
  # Defines ActiveSupport::Deprecation.
27
- require 'active_support/deprecation'
29
+ require "active_support/deprecation"
30
+
31
+ # Defines Regexp#match?.
32
+ #
33
+ # This should be removed when Rails needs Ruby 2.4 or later, and the require
34
+ # added where other Regexp extensions are being used (easy to grep).
35
+ require "active_support/core_ext/regexp"