activesupport 5.1.1 → 6.1.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 (262) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +360 -442
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +5 -4
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +2 -0
  7. data/lib/active_support/array_inquirer.rb +6 -2
  8. data/lib/active_support/backtrace_cleaner.rb +31 -3
  9. data/lib/active_support/benchmarkable.rb +3 -1
  10. data/lib/active_support/builder.rb +2 -0
  11. data/lib/active_support/cache/file_store.rb +37 -36
  12. data/lib/active_support/cache/mem_cache_store.rb +65 -53
  13. data/lib/active_support/cache/memory_store.rb +61 -33
  14. data/lib/active_support/cache/null_store.rb +10 -3
  15. data/lib/active_support/cache/redis_cache_store.rb +493 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +68 -22
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
  18. data/lib/active_support/cache.rb +305 -127
  19. data/lib/active_support/callbacks.rb +106 -98
  20. data/lib/active_support/concern.rb +79 -6
  21. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
  22. data/lib/active_support/concurrency/share_lock.rb +2 -1
  23. data/lib/active_support/configurable.rb +12 -14
  24. data/lib/active_support/configuration_file.rb +46 -0
  25. data/lib/active_support/core_ext/array/access.rb +21 -7
  26. data/lib/active_support/core_ext/array/conversions.rb +7 -5
  27. data/lib/active_support/core_ext/array/extract.rb +21 -0
  28. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  29. data/lib/active_support/core_ext/array/grouping.rb +2 -0
  30. data/lib/active_support/core_ext/array/inquiry.rb +2 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +2 -0
  32. data/lib/active_support/core_ext/array.rb +3 -1
  33. data/lib/active_support/core_ext/benchmark.rb +4 -2
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
  35. data/lib/active_support/core_ext/big_decimal.rb +2 -0
  36. data/lib/active_support/core_ext/class/attribute.rb +50 -47
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
  38. data/lib/active_support/core_ext/class/subclasses.rb +18 -40
  39. data/lib/active_support/core_ext/class.rb +2 -0
  40. data/lib/active_support/core_ext/date/acts_like.rb +2 -0
  41. data/lib/active_support/core_ext/date/blank.rb +2 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +8 -5
  43. data/lib/active_support/core_ext/date/conversions.rb +12 -10
  44. data/lib/active_support/core_ext/date/zones.rb +2 -0
  45. data/lib/active_support/core_ext/date.rb +2 -0
  46. data/lib/active_support/core_ext/date_and_time/calculations.rb +61 -37
  47. data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
  48. data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
  50. data/lib/active_support/core_ext/date_time/blank.rb +2 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
  53. data/lib/active_support/core_ext/date_time/conversions.rb +2 -1
  54. data/lib/active_support/core_ext/date_time.rb +2 -0
  55. data/lib/active_support/core_ext/digest/uuid.rb +3 -1
  56. data/lib/active_support/core_ext/digest.rb +3 -0
  57. data/lib/active_support/core_ext/enumerable.rb +174 -71
  58. data/lib/active_support/core_ext/file/atomic.rb +3 -1
  59. data/lib/active_support/core_ext/file.rb +2 -0
  60. data/lib/active_support/core_ext/hash/conversions.rb +7 -5
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
  62. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  63. data/lib/active_support/core_ext/hash/except.rb +4 -2
  64. data/lib/active_support/core_ext/hash/indifferent_access.rb +2 -0
  65. data/lib/active_support/core_ext/hash/keys.rb +3 -30
  66. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  67. data/lib/active_support/core_ext/hash/slice.rb +8 -29
  68. data/lib/active_support/core_ext/hash.rb +3 -2
  69. data/lib/active_support/core_ext/integer/inflections.rb +2 -0
  70. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  71. data/lib/active_support/core_ext/integer/time.rb +7 -14
  72. data/lib/active_support/core_ext/integer.rb +2 -0
  73. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  74. data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
  75. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  76. data/lib/active_support/core_ext/kernel.rb +2 -1
  77. data/lib/active_support/core_ext/load_error.rb +3 -8
  78. data/lib/active_support/core_ext/marshal.rb +4 -0
  79. data/lib/active_support/core_ext/module/aliasing.rb +2 -0
  80. data/lib/active_support/core_ext/module/anonymous.rb +2 -0
  81. data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
  82. data/lib/active_support/core_ext/module/attribute_accessors.rb +44 -56
  83. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +18 -18
  84. data/lib/active_support/core_ext/module/concerning.rb +15 -10
  85. data/lib/active_support/core_ext/module/delegation.rb +103 -58
  86. data/lib/active_support/core_ext/module/deprecation.rb +2 -0
  87. data/lib/active_support/core_ext/module/introspection.rb +18 -15
  88. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  89. data/lib/active_support/core_ext/module/remove_method.rb +5 -23
  90. data/lib/active_support/core_ext/module.rb +3 -1
  91. data/lib/active_support/core_ext/name_error.rb +36 -2
  92. data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
  93. data/lib/active_support/core_ext/numeric/conversions.rb +131 -129
  94. data/lib/active_support/core_ext/numeric/time.rb +7 -15
  95. data/lib/active_support/core_ext/numeric.rb +2 -1
  96. data/lib/active_support/core_ext/object/acts_like.rb +12 -1
  97. data/lib/active_support/core_ext/object/blank.rb +13 -3
  98. data/lib/active_support/core_ext/object/conversions.rb +2 -0
  99. data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
  100. data/lib/active_support/core_ext/object/duplicable.rb +6 -101
  101. data/lib/active_support/core_ext/object/inclusion.rb +2 -0
  102. data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
  103. data/lib/active_support/core_ext/object/json.rb +22 -2
  104. data/lib/active_support/core_ext/object/to_param.rb +2 -0
  105. data/lib/active_support/core_ext/object/to_query.rb +7 -2
  106. data/lib/active_support/core_ext/object/try.rb +19 -7
  107. data/lib/active_support/core_ext/object/with_options.rb +4 -2
  108. data/lib/active_support/core_ext/object.rb +2 -0
  109. data/lib/active_support/core_ext/range/compare_range.rb +82 -0
  110. data/lib/active_support/core_ext/range/conversions.rb +35 -25
  111. data/lib/active_support/core_ext/range/each.rb +5 -2
  112. data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -0
  113. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  114. data/lib/active_support/core_ext/range.rb +4 -1
  115. data/lib/active_support/core_ext/regexp.rb +10 -5
  116. data/lib/active_support/core_ext/securerandom.rb +25 -3
  117. data/lib/active_support/core_ext/string/access.rb +7 -16
  118. data/lib/active_support/core_ext/string/behavior.rb +2 -0
  119. data/lib/active_support/core_ext/string/conversions.rb +3 -0
  120. data/lib/active_support/core_ext/string/exclude.rb +2 -0
  121. data/lib/active_support/core_ext/string/filters.rb +44 -1
  122. data/lib/active_support/core_ext/string/indent.rb +2 -0
  123. data/lib/active_support/core_ext/string/inflections.rb +69 -16
  124. data/lib/active_support/core_ext/string/inquiry.rb +3 -0
  125. data/lib/active_support/core_ext/string/multibyte.rb +9 -4
  126. data/lib/active_support/core_ext/string/output_safety.rb +76 -20
  127. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  128. data/lib/active_support/core_ext/string/strip.rb +5 -1
  129. data/lib/active_support/core_ext/string/zones.rb +2 -0
  130. data/lib/active_support/core_ext/string.rb +2 -0
  131. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +14 -0
  132. data/lib/active_support/core_ext/symbol.rb +3 -0
  133. data/lib/active_support/core_ext/time/acts_like.rb +2 -0
  134. data/lib/active_support/core_ext/time/calculations.rb +73 -18
  135. data/lib/active_support/core_ext/time/compatibility.rb +4 -2
  136. data/lib/active_support/core_ext/time/conversions.rb +4 -0
  137. data/lib/active_support/core_ext/time/zones.rb +6 -4
  138. data/lib/active_support/core_ext/time.rb +2 -0
  139. data/lib/active_support/core_ext/uri.rb +11 -6
  140. data/lib/active_support/core_ext.rb +3 -1
  141. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  142. data/lib/active_support/current_attributes.rb +208 -0
  143. data/lib/active_support/dependencies/autoload.rb +2 -0
  144. data/lib/active_support/dependencies/interlock.rb +2 -0
  145. data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
  146. data/lib/active_support/dependencies.rb +135 -60
  147. data/lib/active_support/deprecation/behaviors.rb +43 -11
  148. data/lib/active_support/deprecation/constant_accessor.rb +4 -2
  149. data/lib/active_support/deprecation/disallowed.rb +56 -0
  150. data/lib/active_support/deprecation/instance_delegator.rb +2 -1
  151. data/lib/active_support/deprecation/method_wrappers.rb +30 -15
  152. data/lib/active_support/deprecation/proxy_wrappers.rb +32 -6
  153. data/lib/active_support/deprecation/reporting.rb +54 -9
  154. data/lib/active_support/deprecation.rb +9 -2
  155. data/lib/active_support/descendants_tracker.rb +61 -9
  156. data/lib/active_support/digest.rb +20 -0
  157. data/lib/active_support/duration/iso8601_parser.rb +6 -6
  158. data/lib/active_support/duration/iso8601_serializer.rb +20 -14
  159. data/lib/active_support/duration.rb +179 -41
  160. data/lib/active_support/encrypted_configuration.rb +45 -0
  161. data/lib/active_support/encrypted_file.rb +117 -0
  162. data/lib/active_support/environment_inquirer.rb +20 -0
  163. data/lib/active_support/evented_file_update_checker.rb +84 -117
  164. data/lib/active_support/execution_wrapper.rb +3 -0
  165. data/lib/active_support/executor.rb +2 -0
  166. data/lib/active_support/file_update_checker.rb +2 -1
  167. data/lib/active_support/fork_tracker.rb +62 -0
  168. data/lib/active_support/gem_version.rb +3 -1
  169. data/lib/active_support/gzip.rb +2 -0
  170. data/lib/active_support/hash_with_indifferent_access.rb +134 -37
  171. data/lib/active_support/i18n.rb +4 -1
  172. data/lib/active_support/i18n_railtie.rb +20 -11
  173. data/lib/active_support/inflections.rb +2 -0
  174. data/lib/active_support/inflector/inflections.rb +19 -8
  175. data/lib/active_support/inflector/methods.rb +87 -77
  176. data/lib/active_support/inflector/transliterate.rb +56 -18
  177. data/lib/active_support/inflector.rb +2 -0
  178. data/lib/active_support/json/decoding.rb +27 -26
  179. data/lib/active_support/json/encoding.rb +13 -3
  180. data/lib/active_support/json.rb +2 -0
  181. data/lib/active_support/key_generator.rb +3 -33
  182. data/lib/active_support/lazy_load_hooks.rb +33 -10
  183. data/lib/active_support/locale/en.rb +33 -0
  184. data/lib/active_support/locale/en.yml +7 -3
  185. data/lib/active_support/log_subscriber/test_helper.rb +2 -0
  186. data/lib/active_support/log_subscriber.rb +46 -13
  187. data/lib/active_support/logger.rb +4 -17
  188. data/lib/active_support/logger_silence.rb +13 -20
  189. data/lib/active_support/logger_thread_safe_level.rb +54 -7
  190. data/lib/active_support/message_encryptor.rb +101 -33
  191. data/lib/active_support/message_verifier.rb +85 -14
  192. data/lib/active_support/messages/metadata.rb +80 -0
  193. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  194. data/lib/active_support/messages/rotator.rb +57 -0
  195. data/lib/active_support/multibyte/chars.rb +12 -68
  196. data/lib/active_support/multibyte/unicode.rb +17 -327
  197. data/lib/active_support/multibyte.rb +2 -0
  198. data/lib/active_support/notifications/fanout.rb +118 -16
  199. data/lib/active_support/notifications/instrumenter.rb +73 -9
  200. data/lib/active_support/notifications.rb +74 -8
  201. data/lib/active_support/number_helper/number_converter.rb +7 -6
  202. data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
  203. data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -2
  204. data/lib/active_support/number_helper/number_to_human_converter.rb +8 -7
  205. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -3
  206. data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
  207. data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -2
  208. data/lib/active_support/number_helper/number_to_rounded_converter.rb +16 -53
  209. data/lib/active_support/number_helper/rounding_helper.rb +50 -0
  210. data/lib/active_support/number_helper.rb +41 -12
  211. data/lib/active_support/option_merger.rb +24 -3
  212. data/lib/active_support/ordered_hash.rb +3 -1
  213. data/lib/active_support/ordered_options.rb +17 -5
  214. data/lib/active_support/parameter_filter.rb +133 -0
  215. data/lib/active_support/per_thread_registry.rb +3 -1
  216. data/lib/active_support/proxy_object.rb +2 -0
  217. data/lib/active_support/rails.rb +3 -10
  218. data/lib/active_support/railtie.rb +60 -9
  219. data/lib/active_support/reloader.rb +11 -10
  220. data/lib/active_support/rescuable.rb +7 -6
  221. data/lib/active_support/secure_compare_rotator.rb +51 -0
  222. data/lib/active_support/security_utils.rb +26 -15
  223. data/lib/active_support/string_inquirer.rb +6 -3
  224. data/lib/active_support/subscriber.rb +74 -24
  225. data/lib/active_support/tagged_logging.rb +44 -8
  226. data/lib/active_support/test_case.rb +94 -2
  227. data/lib/active_support/testing/assertions.rb +58 -20
  228. data/lib/active_support/testing/autorun.rb +2 -4
  229. data/lib/active_support/testing/constant_lookup.rb +2 -0
  230. data/lib/active_support/testing/declarative.rb +2 -0
  231. data/lib/active_support/testing/deprecation.rb +2 -1
  232. data/lib/active_support/testing/file_fixtures.rb +4 -0
  233. data/lib/active_support/testing/isolation.rb +8 -4
  234. data/lib/active_support/testing/method_call_assertions.rb +30 -1
  235. data/lib/active_support/testing/parallelization/server.rb +78 -0
  236. data/lib/active_support/testing/parallelization/worker.rb +100 -0
  237. data/lib/active_support/testing/parallelization.rb +51 -0
  238. data/lib/active_support/testing/setup_and_teardown.rb +12 -7
  239. data/lib/active_support/testing/stream.rb +3 -2
  240. data/lib/active_support/testing/tagged_logging.rb +2 -0
  241. data/lib/active_support/testing/time_helpers.rb +78 -13
  242. data/lib/active_support/time.rb +2 -0
  243. data/lib/active_support/time_with_zone.rb +113 -41
  244. data/lib/active_support/values/time_zone.rb +55 -25
  245. data/lib/active_support/version.rb +2 -0
  246. data/lib/active_support/xml_mini/jdom.rb +5 -4
  247. data/lib/active_support/xml_mini/libxml.rb +4 -2
  248. data/lib/active_support/xml_mini/libxmlsax.rb +6 -4
  249. data/lib/active_support/xml_mini/nokogiri.rb +4 -2
  250. data/lib/active_support/xml_mini/nokogirisax.rb +5 -3
  251. data/lib/active_support/xml_mini/rexml.rb +12 -3
  252. data/lib/active_support/xml_mini.rb +5 -11
  253. data/lib/active_support.rb +18 -13
  254. metadata +81 -35
  255. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  256. data/lib/active_support/core_ext/hash/compact.rb +0 -27
  257. data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
  258. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  259. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  260. data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
  261. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  262. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/xml_mini"
2
- require "active_support/time"
3
4
  require "active_support/core_ext/object/blank"
4
5
  require "active_support/core_ext/object/to_param"
5
6
  require "active_support/core_ext/object/to_query"
7
+ require "active_support/core_ext/object/try"
6
8
  require "active_support/core_ext/array/wrap"
7
9
  require "active_support/core_ext/hash/reverse_merge"
8
10
  require "active_support/core_ext/string/inflections"
@@ -71,7 +73,7 @@ class Hash
71
73
  # configure your own builder with the <tt>:builder</tt> option. The method also accepts
72
74
  # options like <tt>:dasherize</tt> and friends, they are forwarded to the builder.
73
75
  def to_xml(options = {})
74
- require "active_support/builder" unless defined?(Builder)
76
+ require "active_support/builder" unless defined?(Builder::XmlMarkup)
75
77
 
76
78
  options = options.dup
77
79
  options[:indent] ||= 2
@@ -163,7 +165,7 @@ module ActiveSupport
163
165
  Hash[params.map { |k, v| [k.to_s.tr("-", "_"), normalize_keys(v)] } ]
164
166
  when Array
165
167
  params.map { |v| normalize_keys(v) }
166
- else
168
+ else
167
169
  params
168
170
  end
169
171
  end
@@ -176,7 +178,7 @@ module ActiveSupport
176
178
  process_array(value)
177
179
  when String
178
180
  value
179
- else
181
+ else
180
182
  raise "can't typecast #{value.class.name} - #{value.inspect}"
181
183
  end
182
184
  end
@@ -206,7 +208,7 @@ module ActiveSupport
206
208
  elsif become_empty_string?(value)
207
209
  ""
208
210
  elsif become_hash?(value)
209
- xml_value = Hash[value.map { |k, v| [k, deep_to_h(v)] }]
211
+ xml_value = value.transform_values { |v| deep_to_h(v) }
210
212
 
211
213
  # Turn { files: { file: #<StringIO> } } into { files: #<StringIO> } so it is compatible with
212
214
  # how multipart uploaded files from HTML appear
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Hash
2
4
  # Returns a new hash with +self+ and +other_hash+ merged recursively.
3
5
  #
@@ -19,20 +21,14 @@ class Hash
19
21
 
20
22
  # Same as +deep_merge+, but modifies +self+.
21
23
  def deep_merge!(other_hash, &block)
22
- other_hash.each_pair do |current_key, other_value|
23
- this_value = self[current_key]
24
-
25
- self[current_key] = if this_value.is_a?(Hash) && other_value.is_a?(Hash)
26
- this_value.deep_merge(other_value, &block)
24
+ merge!(other_hash) do |key, this_val, other_val|
25
+ if this_val.is_a?(Hash) && other_val.is_a?(Hash)
26
+ this_val.deep_merge(other_val, &block)
27
+ elsif block_given?
28
+ block.call(key, this_val, other_val)
27
29
  else
28
- if block_given? && key?(current_key)
29
- block.call(current_key, this_value, other_value)
30
- else
31
- other_value
32
- end
30
+ other_val
33
31
  end
34
32
  end
35
-
36
- self
37
33
  end
38
34
  end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Hash
4
+ # Returns a new hash with all values converted by the block operation.
5
+ # This includes the values from the root hash and from all
6
+ # nested hashes and arrays.
7
+ #
8
+ # hash = { person: { name: 'Rob', age: '28' } }
9
+ #
10
+ # hash.deep_transform_values{ |value| value.to_s.upcase }
11
+ # # => {person: {name: "ROB", age: "28"}}
12
+ def deep_transform_values(&block)
13
+ _deep_transform_values_in_object(self, &block)
14
+ end
15
+
16
+ # Destructively converts all values by using the block operation.
17
+ # This includes the values from the root hash and from all
18
+ # nested hashes and arrays.
19
+ def deep_transform_values!(&block)
20
+ _deep_transform_values_in_object!(self, &block)
21
+ end
22
+
23
+ private
24
+ # Support methods for deep transforming nested hashes and arrays.
25
+ def _deep_transform_values_in_object(object, &block)
26
+ case object
27
+ when Hash
28
+ object.transform_values { |value| _deep_transform_values_in_object(value, &block) }
29
+ when Array
30
+ object.map { |e| _deep_transform_values_in_object(e, &block) }
31
+ else
32
+ yield(object)
33
+ end
34
+ end
35
+
36
+ def _deep_transform_values_in_object!(object, &block)
37
+ case object
38
+ when Hash
39
+ object.transform_values! { |value| _deep_transform_values_in_object!(value, &block) }
40
+ when Array
41
+ object.map! { |e| _deep_transform_values_in_object!(e, &block) }
42
+ else
43
+ yield(object)
44
+ end
45
+ end
46
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Hash
2
4
  # Returns a hash that includes everything except given keys.
3
5
  # hash = { a: true, b: false, c: nil }
@@ -8,8 +10,8 @@ class Hash
8
10
  # This is useful for limiting a set of parameters to everything but a few known toggles:
9
11
  # @person.update(params[:person].except(:admin))
10
12
  def except(*keys)
11
- dup.except!(*keys)
12
- end
13
+ slice(*self.keys - keys)
14
+ end unless method_defined?(:except)
13
15
 
14
16
  # Removes the given keys from hash and returns it.
15
17
  # hash = { a: true, b: false, c: nil }
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/hash_with_indifferent_access"
2
4
 
3
5
  class Hash
@@ -1,33 +1,6 @@
1
- class Hash
2
- # Returns a new hash with all keys converted using the +block+ operation.
3
- #
4
- # hash = { name: 'Rob', age: '28' }
5
- #
6
- # hash.transform_keys { |key| key.to_s.upcase } # => {"NAME"=>"Rob", "AGE"=>"28"}
7
- #
8
- # If you do not provide a +block+, it will return an Enumerator
9
- # for chaining with other methods:
10
- #
11
- # hash.transform_keys.with_index { |k, i| [k, i].join } # => {"name0"=>"Rob", "age1"=>"28"}
12
- def transform_keys
13
- return enum_for(:transform_keys) { size } unless block_given?
14
- result = {}
15
- each_key do |key|
16
- result[yield(key)] = self[key]
17
- end
18
- result
19
- end
20
-
21
- # Destructively converts all keys using the +block+ operations.
22
- # Same as +transform_keys+ but modifies +self+.
23
- def transform_keys!
24
- return enum_for(:transform_keys!) { size } unless block_given?
25
- keys.each do |key|
26
- self[yield(key)] = delete(key)
27
- end
28
- self
29
- end
1
+ # frozen_string_literal: true
30
2
 
3
+ class Hash
31
4
  # Returns a new hash with all keys converted to strings.
32
5
  #
33
6
  # hash = { name: 'Rob', age: '28' }
@@ -139,7 +112,7 @@ class Hash
139
112
  end
140
113
 
141
114
  private
142
- # support methods for deep transforming nested hashes and arrays
115
+ # Support methods for deep transforming nested hashes and arrays.
143
116
  def _deep_transform_keys_in_object(object, &block)
144
117
  case object
145
118
  when Hash
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Hash
2
4
  # Merges the caller into +other_hash+. For example,
3
5
  #
@@ -12,11 +14,12 @@ class Hash
12
14
  def reverse_merge(other_hash)
13
15
  other_hash.merge(self)
14
16
  end
17
+ alias_method :with_defaults, :reverse_merge
15
18
 
16
19
  # Destructive +reverse_merge+.
17
20
  def reverse_merge!(other_hash)
18
- # right wins if there is no left
19
- merge!(other_hash) { |key, left, right| left }
21
+ replace(reverse_merge(other_hash))
20
22
  end
21
23
  alias_method :reverse_update, :reverse_merge!
24
+ alias_method :with_defaults!, :reverse_merge!
22
25
  end
@@ -1,35 +1,13 @@
1
- class Hash
2
- # Slices a hash to include only the given keys. Returns a hash containing
3
- # the given keys.
4
- #
5
- # { a: 1, b: 2, c: 3, d: 4 }.slice(:a, :b)
6
- # # => {:a=>1, :b=>2}
7
- #
8
- # This is useful for limiting an options hash to valid keys before
9
- # passing to a method:
10
- #
11
- # def search(criteria = {})
12
- # criteria.assert_valid_keys(:mass, :velocity, :time)
13
- # end
14
- #
15
- # search(options.slice(:mass, :velocity, :time))
16
- #
17
- # If you have an array of keys you want to limit to, you should splat them:
18
- #
19
- # valid_keys = [:mass, :velocity, :time]
20
- # search(options.slice(*valid_keys))
21
- def slice(*keys)
22
- keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
23
- keys.each_with_object(self.class.new) { |k, hash| hash[k] = self[k] if has_key?(k) }
24
- end
1
+ # frozen_string_literal: true
25
2
 
3
+ class Hash
26
4
  # Replaces the hash with only the given keys.
27
5
  # Returns a hash containing the removed key/value pairs.
28
6
  #
29
- # { a: 1, b: 2, c: 3, d: 4 }.slice!(:a, :b)
30
- # # => {:c=>3, :d=>4}
7
+ # hash = { a: 1, b: 2, c: 3, d: 4 }
8
+ # hash.slice!(:a, :b) # => {:c=>3, :d=>4}
9
+ # hash # => {:a=>1, :b=>2}
31
10
  def slice!(*keys)
32
- keys.map! { |key| convert_key(key) } if respond_to?(:convert_key, true)
33
11
  omit = slice(*self.keys - keys)
34
12
  hash = slice(*keys)
35
13
  hash.default = default
@@ -40,8 +18,9 @@ class Hash
40
18
 
41
19
  # Removes and returns the key/value pairs matching the given keys.
42
20
  #
43
- # { a: 1, b: 2, c: 3, d: 4 }.extract!(:a, :b) # => {:a=>1, :b=>2}
44
- # { a: 1, b: 2 }.extract!(:a, :x) # => {:a=>1}
21
+ # hash = { a: 1, b: 2, c: 3, d: 4 }
22
+ # hash.extract!(:a, :b) # => {:a=>1, :b=>2}
23
+ # hash # => {:c=>3, :d=>4}
45
24
  def extract!(*keys)
46
25
  keys.each_with_object(self.class.new) { |key, result| result[key] = delete(key) if has_key?(key) }
47
26
  end
@@ -1,9 +1,10 @@
1
- require "active_support/core_ext/hash/compact"
1
+ # frozen_string_literal: true
2
+
2
3
  require "active_support/core_ext/hash/conversions"
3
4
  require "active_support/core_ext/hash/deep_merge"
5
+ require "active_support/core_ext/hash/deep_transform_values"
4
6
  require "active_support/core_ext/hash/except"
5
7
  require "active_support/core_ext/hash/indifferent_access"
6
8
  require "active_support/core_ext/hash/keys"
7
9
  require "active_support/core_ext/hash/reverse_merge"
8
10
  require "active_support/core_ext/hash/slice"
9
- require "active_support/core_ext/hash/transform_values"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/inflector"
2
4
 
3
5
  class Integer
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Integer
2
4
  # Check whether the integer is evenly divisible by the argument.
3
5
  #
@@ -5,6 +7,6 @@ class Integer
5
7
  # 6.multiple_of?(5) # => false
6
8
  # 10.multiple_of?(2) # => true
7
9
  def multiple_of?(number)
8
- number != 0 ? self % number == 0 : zero?
10
+ number == 0 ? self == 0 : self % number == 0
9
11
  end
10
12
  end
@@ -1,27 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/duration"
2
4
  require "active_support/core_ext/numeric/time"
3
5
 
4
6
  class Integer
5
- # Enables the use of time calculations and declarations, like <tt>45.minutes +
6
- # 2.hours + 4.years</tt>.
7
- #
8
- # These methods use Time#advance for precise date calculations when using
9
- # <tt>from_now</tt>, +ago+, etc. as well as adding or subtracting their
10
- # results from a Time object.
11
- #
12
- # # equivalent to Time.now.advance(months: 1)
13
- # 1.month.from_now
7
+ # Returns a Duration instance matching the number of months provided.
14
8
  #
15
- # # equivalent to Time.now.advance(years: 2)
16
- # 2.years.from_now
17
- #
18
- # # equivalent to Time.now.advance(months: 4, years: 5)
19
- # (4.months + 5.years).from_now
9
+ # 2.months # => 2 months
20
10
  def months
21
11
  ActiveSupport::Duration.months(self)
22
12
  end
23
13
  alias :month :months
24
14
 
15
+ # Returns a Duration instance matching the number of years provided.
16
+ #
17
+ # 2.years # => 2 years
25
18
  def years
26
19
  ActiveSupport::Duration.years(self)
27
20
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/integer/multiple"
2
4
  require "active_support/core_ext/integer/inflections"
3
5
  require "active_support/core_ext/integer/time"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/core_ext/module/concerning"
2
4
 
3
5
  module Kernel
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kernel
2
4
  module_function
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Kernel
2
4
  # class_eval on an object acts like singleton_class.class_eval.
3
5
  def class_eval(*args, &block)
@@ -1,4 +1,5 @@
1
- require "active_support/core_ext/kernel/agnostics"
1
+ # frozen_string_literal: true
2
+
2
3
  require "active_support/core_ext/kernel/concern"
3
4
  require "active_support/core_ext/kernel/reporting"
4
5
  require "active_support/core_ext/kernel/singleton_class"
@@ -1,14 +1,9 @@
1
- class LoadError
2
- REGEXPS = [
3
- /^no such file to load -- (.+)$/i,
4
- /^Missing \w+ (?:file\s*)?([^\s]+.rb)$/i,
5
- /^Missing API definition file in (.+)$/i,
6
- /^cannot load such file -- (.+)$/i,
7
- ]
1
+ # frozen_string_literal: true
8
2
 
3
+ class LoadError
9
4
  # Returns true if the given path name (except perhaps for the ".rb"
10
5
  # extension) is the missing file which caused the exception to be raised.
11
6
  def is_missing?(location)
12
- location.sub(/\.rb$/, "".freeze) == path.sub(/\.rb$/, "".freeze)
7
+ location.delete_suffix(".rb") == path.to_s.delete_suffix(".rb")
13
8
  end
14
9
  end
@@ -1,3 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/string/inflections"
4
+
1
5
  module ActiveSupport
2
6
  module MarshalWithAutoloading # :nodoc:
3
7
  def load(source, proc = nil)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Module
2
4
  # Allows you to make aliases for attributes, which includes
3
5
  # getter, setter, and a predicate.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Module
2
4
  # A module may or may not have a name.
3
5
  #
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Module
2
4
  # Declares an attribute reader backed by an internally-named instance variable.
3
5
  def attr_internal_reader(*attrs)
@@ -26,9 +28,9 @@ class Module
26
28
  end
27
29
 
28
30
  def attr_internal_define(attr_name, type)
29
- internal_name = attr_internal_ivar_name(attr_name).sub(/\A@/, "")
31
+ internal_name = attr_internal_ivar_name(attr_name).delete_prefix("@")
30
32
  # use native attr_* methods as they are faster on some Ruby implementations
31
- send("attr_#{type}", internal_name)
33
+ public_send("attr_#{type}", internal_name)
32
34
  attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer
33
35
  alias_method attr_name, internal_name
34
36
  remove_method internal_name
@@ -1,5 +1,4 @@
1
- require "active_support/core_ext/array/extract_options"
2
- require "active_support/core_ext/regexp"
1
+ # frozen_string_literal: true
3
2
 
4
3
  # Extends the module object with class/module and instance accessors for
5
4
  # class/module attributes, just like the native attr* accessors for instance
@@ -25,7 +24,7 @@ class Module
25
24
  # end
26
25
  # # => NameError: invalid attribute name: 1_Badname
27
26
  #
28
- # If you want to opt out the creation on the instance reader method, pass
27
+ # To omit the instance reader method, pass
29
28
  # <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
30
29
  #
31
30
  # module HairColors
@@ -38,13 +37,10 @@ class Module
38
37
  #
39
38
  # Person.new.hair_colors # => NoMethodError
40
39
  #
41
- #
42
- # Also, you can pass a block to set up the attribute with a default value.
40
+ # You can set a default value for the attribute.
43
41
  #
44
42
  # module HairColors
45
- # mattr_reader :hair_colors do
46
- # [:brown, :black, :blonde, :red]
47
- # end
43
+ # mattr_reader :hair_colors, default: [:brown, :black, :blonde, :red]
48
44
  # end
49
45
  #
50
46
  # class Person
@@ -52,27 +48,25 @@ class Module
52
48
  # end
53
49
  #
54
50
  # Person.new.hair_colors # => [:brown, :black, :blonde, :red]
55
- def mattr_reader(*syms)
56
- options = syms.extract_options!
51
+ def mattr_reader(*syms, instance_reader: true, instance_accessor: true, default: nil, location: nil)
52
+ raise TypeError, "module attributes should be defined directly on class, not singleton" if singleton_class?
53
+ location ||= caller_locations(1, 1).first
54
+
55
+ definition = []
57
56
  syms.each do |sym|
58
57
  raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
59
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
60
- @@#{sym} = nil unless defined? @@#{sym}
61
58
 
62
- def self.#{sym}
63
- @@#{sym}
64
- end
65
- EOS
59
+ definition << "def self.#{sym}; @@#{sym}; end"
66
60
 
67
- unless options[:instance_reader] == false || options[:instance_accessor] == false
68
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
69
- def #{sym}
70
- @@#{sym}
71
- end
72
- EOS
61
+ if instance_reader && instance_accessor
62
+ definition << "def #{sym}; @@#{sym}; end"
73
63
  end
74
- class_variable_set("@@#{sym}", yield) if block_given?
64
+
65
+ sym_default_value = (block_given? && default.nil?) ? yield : default
66
+ class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? && class_variable_defined?("@@#{sym}")
75
67
  end
68
+
69
+ module_eval(definition.join(";"), location.path, location.lineno)
76
70
  end
77
71
  alias :cattr_reader :mattr_reader
78
72
 
@@ -94,7 +88,7 @@ class Module
94
88
  # Person.new.hair_colors = [:blonde, :red]
95
89
  # HairColors.class_variable_get("@@hair_colors") # => [:blonde, :red]
96
90
  #
97
- # If you want to opt out the instance writer method, pass
91
+ # To omit the instance writer method, pass
98
92
  # <tt>instance_writer: false</tt> or <tt>instance_accessor: false</tt>.
99
93
  #
100
94
  # module HairColors
@@ -107,12 +101,10 @@ class Module
107
101
  #
108
102
  # Person.new.hair_colors = [:blonde, :red] # => NoMethodError
109
103
  #
110
- # Also, you can pass a block to set up the attribute with a default value.
104
+ # You can set a default value for the attribute.
111
105
  #
112
106
  # module HairColors
113
- # mattr_writer :hair_colors do
114
- # [:brown, :black, :blonde, :red]
115
- # end
107
+ # mattr_writer :hair_colors, default: [:brown, :black, :blonde, :red]
116
108
  # end
117
109
  #
118
110
  # class Person
@@ -120,27 +112,24 @@ class Module
120
112
  # end
121
113
  #
122
114
  # Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
123
- def mattr_writer(*syms)
124
- options = syms.extract_options!
115
+ def mattr_writer(*syms, instance_writer: true, instance_accessor: true, default: nil, location: nil)
116
+ raise TypeError, "module attributes should be defined directly on class, not singleton" if singleton_class?
117
+ location ||= caller_locations(1, 1).first
118
+
119
+ definition = []
125
120
  syms.each do |sym|
126
121
  raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
127
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
128
- @@#{sym} = nil unless defined? @@#{sym}
129
-
130
- def self.#{sym}=(obj)
131
- @@#{sym} = obj
132
- end
133
- EOS
122
+ definition << "def self.#{sym}=(val); @@#{sym} = val; end"
134
123
 
135
- unless options[:instance_writer] == false || options[:instance_accessor] == false
136
- class_eval(<<-EOS, __FILE__, __LINE__ + 1)
137
- def #{sym}=(obj)
138
- @@#{sym} = obj
139
- end
140
- EOS
124
+ if instance_writer && instance_accessor
125
+ definition << "def #{sym}=(val); @@#{sym} = val; end"
141
126
  end
142
- send("#{sym}=", yield) if block_given?
127
+
128
+ sym_default_value = (block_given? && default.nil?) ? yield : default
129
+ class_variable_set("@@#{sym}", sym_default_value) unless sym_default_value.nil? && class_variable_defined?("@@#{sym}")
143
130
  end
131
+
132
+ module_eval(definition.join(";"), location.path, location.lineno)
144
133
  end
145
134
  alias :cattr_writer :mattr_writer
146
135
 
@@ -164,14 +153,14 @@ class Module
164
153
  # parent class. Similarly if parent class changes the value then that would
165
154
  # change the value of subclasses too.
166
155
  #
167
- # class Male < Person
156
+ # class Citizen < Person
168
157
  # end
169
158
  #
170
- # Male.new.hair_colors << :blue
159
+ # Citizen.new.hair_colors << :blue
171
160
  # Person.new.hair_colors # => [:brown, :black, :blonde, :red, :blue]
172
161
  #
173
- # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
174
- # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
162
+ # To omit the instance writer method, pass <tt>instance_writer: false</tt>.
163
+ # To omit the instance reader method, pass <tt>instance_reader: false</tt>.
175
164
  #
176
165
  # module HairColors
177
166
  # mattr_accessor :hair_colors, instance_writer: false, instance_reader: false
@@ -184,7 +173,7 @@ class Module
184
173
  # Person.new.hair_colors = [:brown] # => NoMethodError
185
174
  # Person.new.hair_colors # => NoMethodError
186
175
  #
187
- # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
176
+ # Or pass <tt>instance_accessor: false</tt>, to omit both instance methods.
188
177
  #
189
178
  # module HairColors
190
179
  # mattr_accessor :hair_colors, instance_accessor: false
@@ -197,12 +186,10 @@ class Module
197
186
  # Person.new.hair_colors = [:brown] # => NoMethodError
198
187
  # Person.new.hair_colors # => NoMethodError
199
188
  #
200
- # Also you can pass a block to set up the attribute with a default value.
189
+ # You can set a default value for the attribute.
201
190
  #
202
191
  # module HairColors
203
- # mattr_accessor :hair_colors do
204
- # [:brown, :black, :blonde, :red]
205
- # end
192
+ # mattr_accessor :hair_colors, default: [:brown, :black, :blonde, :red]
206
193
  # end
207
194
  #
208
195
  # class Person
@@ -210,9 +197,10 @@ class Module
210
197
  # end
211
198
  #
212
199
  # Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
213
- def mattr_accessor(*syms, &blk)
214
- mattr_reader(*syms, &blk)
215
- mattr_writer(*syms)
200
+ def mattr_accessor(*syms, instance_reader: true, instance_writer: true, instance_accessor: true, default: nil, &blk)
201
+ location = caller_locations(1, 1).first
202
+ mattr_reader(*syms, instance_reader: instance_reader, instance_accessor: instance_accessor, default: default, location: location, &blk)
203
+ mattr_writer(*syms, instance_writer: instance_writer, instance_accessor: instance_accessor, default: default, location: location)
216
204
  end
217
205
  alias :cattr_accessor :mattr_accessor
218
206
  end