activesupport 4.0.12 → 7.0.2.4
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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +249 -501
- data/MIT-LICENSE +2 -2
- data/README.rdoc +10 -5
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +41 -13
- data/lib/active_support/benchmarkable.rb +7 -15
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +96 -74
- data/lib/active_support/cache/mem_cache_store.rb +211 -103
- data/lib/active_support/cache/memory_store.rb +90 -58
- data/lib/active_support/cache/null_store.rb +19 -7
- data/lib/active_support/cache/redis_cache_store.rb +468 -0
- data/lib/active_support/cache/strategy/local_cache.rb +86 -83
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/cache.rb +580 -241
- data/lib/active_support/callbacks.rb +812 -425
- data/lib/active_support/code_generator.rb +65 -0
- data/lib/active_support/concern.rb +103 -14
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +33 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +21 -19
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +47 -1
- data/lib/active_support/core_ext/array/conversions.rb +35 -44
- data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +26 -16
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +10 -7
- data/lib/active_support/core_ext/benchmark.rb +5 -3
- data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +52 -49
- data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
- data/lib/active_support/core_ext/class/subclasses.rb +25 -26
- data/lib/active_support/core_ext/class.rb +4 -4
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +31 -18
- data/lib/active_support/core_ext/date/conversions.rb +43 -32
- data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/date/zones.rb +5 -34
- data/lib/active_support/core_ext/date.rb +7 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +198 -66
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +31 -0
- data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +79 -38
- data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +31 -26
- data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/date_time.rb +8 -4
- data/lib/active_support/core_ext/digest/uuid.rb +79 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +249 -17
- data/lib/active_support/core_ext/file/atomic.rb +41 -32
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +71 -49
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +14 -5
- data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
- data/lib/active_support/core_ext/hash/keys.rb +39 -56
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -23
- data/lib/active_support/core_ext/hash.rb +10 -8
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +11 -33
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +9 -78
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -4
- data/lib/active_support/core_ext/load_error.rb +5 -21
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -8
- data/lib/active_support/core_ext/module/attribute_accessors.rb +186 -44
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +157 -0
- data/lib/active_support/core_ext/module/concerning.rb +140 -0
- data/lib/active_support/core_ext/module/delegation.rb +172 -45
- data/lib/active_support/core_ext/module/deprecation.rb +3 -3
- data/lib/active_support/core_ext/module/introspection.rb +23 -38
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +13 -10
- data/lib/active_support/core_ext/name_error.rb +45 -4
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +135 -127
- data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
- data/lib/active_support/core_ext/numeric/time.rb +37 -50
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/object/acts_like.rb +41 -6
- data/lib/active_support/core_ext/object/blank.rb +70 -20
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
- data/lib/active_support/core_ext/object/duplicable.rb +17 -47
- data/lib/active_support/core_ext/object/inclusion.rb +18 -15
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +244 -0
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +21 -8
- data/lib/active_support/core_ext/object/try.rb +106 -26
- data/lib/active_support/core_ext/object/with_options.rb +64 -5
- data/lib/active_support/core_ext/object.rb +14 -12
- data/lib/active_support/core_ext/pathname/existence.rb +21 -0
- data/lib/active_support/core_ext/pathname.rb +3 -0
- data/lib/active_support/core_ext/range/compare_range.rb +57 -0
- data/lib/active_support/core_ext/range/conversions.rb +37 -15
- data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
- data/lib/active_support/core_ext/range/each.rb +18 -17
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +10 -1
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string/access.rb +42 -51
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +18 -13
- data/lib/active_support/core_ext/string/exclude.rb +5 -3
- data/lib/active_support/core_ext/string/filters.rb +97 -7
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +106 -25
- data/lib/active_support/core_ext/string/inquiry.rb +4 -1
- data/lib/active_support/core_ext/string/multibyte.rb +18 -9
- data/lib/active_support/core_ext/string/output_safety.rb +227 -54
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +6 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -1
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +178 -116
- data/lib/active_support/core_ext/time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/time/conversions.rb +37 -25
- data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
- data/lib/active_support/core_ext/time/zones.rb +44 -42
- data/lib/active_support/core_ext/time.rb +8 -5
- data/lib/active_support/core_ext/uri.rb +4 -25
- data/lib/active_support/core_ext.rb +4 -2
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +226 -0
- data/lib/active_support/dependencies/autoload.rb +3 -1
- data/lib/active_support/dependencies/interlock.rb +49 -0
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +71 -696
- data/lib/active_support/deprecation/behaviors.rb +65 -16
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +16 -2
- data/lib/active_support/deprecation/method_wrappers.rb +62 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +82 -31
- data/lib/active_support/deprecation/reporting.rb +81 -18
- data/lib/active_support/deprecation.rb +19 -11
- data/lib/active_support/descendants_tracker.rb +192 -34
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +67 -0
- data/lib/active_support/duration.rb +437 -39
- data/lib/active_support/encrypted_configuration.rb +56 -0
- data/lib/active_support/encrypted_file.rb +117 -0
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/error_reporter.rb +117 -0
- data/lib/active_support/evented_file_update_checker.rb +170 -0
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +53 -0
- data/lib/active_support/execution_wrapper.rb +151 -0
- data/lib/active_support/executor/test_helper.rb +7 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +62 -37
- data/lib/active_support/fork_tracker.rb +71 -0
- data/lib/active_support/gem_version.rb +17 -0
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +207 -54
- data/lib/active_support/html_safe_translation.rb +43 -0
- data/lib/active_support/i18n.rb +10 -6
- data/lib/active_support/i18n_railtie.rb +48 -19
- data/lib/active_support/inflections.rb +19 -12
- data/lib/active_support/inflector/inflections.rb +97 -37
- data/lib/active_support/inflector/methods.rb +192 -157
- data/lib/active_support/inflector/transliterate.rb +83 -33
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/isolated_execution_state.rb +64 -0
- data/lib/active_support/json/decoding.rb +37 -42
- data/lib/active_support/json/encoding.rb +93 -293
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +30 -47
- data/lib/active_support/lazy_load_hooks.rb +54 -21
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +10 -4
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +61 -18
- data/lib/active_support/logger.rb +40 -4
- data/lib/active_support/logger_silence.rb +17 -20
- data/lib/active_support/logger_thread_safe_level.rb +69 -0
- data/lib/active_support/message_encryptor.rb +178 -55
- data/lib/active_support/message_verifier.rb +195 -26
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +45 -92
- data/lib/active_support/multibyte/unicode.rb +44 -377
- data/lib/active_support/multibyte.rb +5 -3
- data/lib/active_support/notifications/fanout.rb +177 -44
- data/lib/active_support/notifications/instrumenter.rb +117 -17
- data/lib/active_support/notifications.rb +106 -39
- data/lib/active_support/number_helper/number_converter.rb +181 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +59 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
- data/lib/active_support/number_helper/rounding_helper.rb +46 -0
- data/lib/active_support/number_helper.rb +152 -394
- data/lib/active_support/option_merger.rb +18 -5
- data/lib/active_support/ordered_hash.rb +8 -6
- data/lib/active_support/ordered_options.rb +43 -7
- data/lib/active_support/parameter_filter.rb +138 -0
- data/lib/active_support/per_thread_registry.rb +24 -11
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +10 -11
- data/lib/active_support/railtie.rb +118 -12
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +112 -57
- data/lib/active_support/ruby_features.rb +7 -0
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +38 -0
- data/lib/active_support/string_inquirer.rb +11 -4
- data/lib/active_support/subscriber.rb +109 -39
- data/lib/active_support/tagged_logging.rb +54 -17
- data/lib/active_support/test_case.rb +121 -37
- data/lib/active_support/testing/assertions.rb +177 -39
- data/lib/active_support/testing/autorun.rb +5 -3
- data/lib/active_support/testing/constant_lookup.rb +3 -6
- data/lib/active_support/testing/declarative.rb +10 -22
- data/lib/active_support/testing/deprecation.rb +65 -11
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +56 -87
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- data/lib/active_support/testing/parallelization/server.rb +82 -0
- data/lib/active_support/testing/parallelization/worker.rb +103 -0
- data/lib/active_support/testing/parallelization.rb +55 -0
- data/lib/active_support/testing/parallelize_executor.rb +76 -0
- data/lib/active_support/testing/setup_and_teardown.rb +30 -10
- data/lib/active_support/testing/stream.rb +41 -0
- data/lib/active_support/testing/tagged_logging.rb +6 -4
- data/lib/active_support/testing/time_helpers.rb +246 -0
- data/lib/active_support/time.rb +13 -13
- data/lib/active_support/time_with_zone.rb +315 -90
- data/lib/active_support/values/time_zone.rb +306 -135
- data/lib/active_support/version.rb +6 -7
- data/lib/active_support/xml_mini/jdom.rb +117 -115
- data/lib/active_support/xml_mini/libxml.rb +22 -21
- data/lib/active_support/xml_mini/libxmlsax.rb +17 -19
- data/lib/active_support/xml_mini/nokogiri.rb +19 -19
- data/lib/active_support/xml_mini/nokogirisax.rb +16 -17
- data/lib/active_support/xml_mini/rexml.rb +25 -17
- data/lib/active_support/xml_mini.rb +67 -56
- data/lib/active_support.rb +58 -3
- metadata +125 -66
- data/lib/active_support/basic_object.rb +0 -11
- data/lib/active_support/buffered_logger.rb +0 -21
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
- data/lib/active_support/core_ext/date_time/zones.rb +0 -24
- data/lib/active_support/core_ext/hash/diff.rb +0 -14
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/logger.rb +0 -67
- data/lib/active_support/core_ext/marshal.rb +0 -21
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/object/to_json.rb +0 -27
- data/lib/active_support/core_ext/proc.rb +0 -17
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/core_ext/string/encoding.rb +0 -8
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -79
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
- data/lib/active_support/file_watcher.rb +0 -36
- data/lib/active_support/json/variable.rb +0 -18
- data/lib/active_support/testing/pending.rb +0 -14
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/time/calculations"
|
4
|
+
|
1
5
|
module ActiveSupport
|
2
6
|
# FileUpdateChecker specifies the API used by Rails to watch files
|
3
7
|
# and control reloading. The API depends on four methods:
|
@@ -23,7 +27,7 @@ module ActiveSupport
|
|
23
27
|
# I18n.reload!
|
24
28
|
# end
|
25
29
|
#
|
26
|
-
#
|
30
|
+
# ActiveSupport::Reloader.to_prepare do
|
27
31
|
# i18n_reloader.execute_if_updated
|
28
32
|
# end
|
29
33
|
class FileUpdateChecker
|
@@ -35,7 +39,11 @@ module ActiveSupport
|
|
35
39
|
# This method must also receive a block that will be called once a path
|
36
40
|
# changes. The array of files and list of directories cannot be changed
|
37
41
|
# after FileUpdateChecker has been initialized.
|
38
|
-
def initialize(files, dirs={}, &block)
|
42
|
+
def initialize(files, dirs = {}, &block)
|
43
|
+
unless block
|
44
|
+
raise ArgumentError, "A block is required to initialize a FileUpdateChecker"
|
45
|
+
end
|
46
|
+
|
39
47
|
@files = files.freeze
|
40
48
|
@glob = compile_glob(dirs)
|
41
49
|
@block = block
|
@@ -81,6 +89,7 @@ module ActiveSupport
|
|
81
89
|
# Execute the block given if updated.
|
82
90
|
def execute_if_updated
|
83
91
|
if updated?
|
92
|
+
yield if block_given?
|
84
93
|
execute
|
85
94
|
true
|
86
95
|
else
|
@@ -89,49 +98,65 @@ module ActiveSupport
|
|
89
98
|
end
|
90
99
|
|
91
100
|
private
|
101
|
+
def watched
|
102
|
+
@watched || begin
|
103
|
+
all = @files.select { |f| File.exist?(f) }
|
104
|
+
all.concat(Dir[@glob]) if @glob
|
105
|
+
all
|
106
|
+
end
|
107
|
+
end
|
92
108
|
|
93
|
-
|
94
|
-
|
95
|
-
all = @files.select { |f| File.exist?(f) }
|
96
|
-
all.concat(Dir[@glob]) if @glob
|
97
|
-
all
|
109
|
+
def updated_at(paths)
|
110
|
+
@updated_at || max_mtime(paths) || Time.at(0)
|
98
111
|
end
|
99
|
-
end
|
100
112
|
|
101
|
-
|
102
|
-
|
103
|
-
|
113
|
+
# This method returns the maximum mtime of the files in +paths+, or +nil+
|
114
|
+
# if the array is empty.
|
115
|
+
#
|
116
|
+
# Files with a mtime in the future are ignored. Such abnormal situation
|
117
|
+
# can happen for example if the user changes the clock by hand. It is
|
118
|
+
# healthy to consider this edge case because with mtimes in the future
|
119
|
+
# reloading is not triggered.
|
120
|
+
def max_mtime(paths)
|
121
|
+
time_now = Time.now
|
122
|
+
max_mtime = nil
|
104
123
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
def max_mtime(paths)
|
113
|
-
time_now = Time.now
|
114
|
-
paths.map {|path| File.mtime(path)}.reject {|mtime| time_now < mtime}.max
|
115
|
-
end
|
124
|
+
# Time comparisons are performed with #compare_without_coercion because
|
125
|
+
# AS redefines these operators in a way that is much slower and does not
|
126
|
+
# bring any benefit in this particular code.
|
127
|
+
#
|
128
|
+
# Read t1.compare_without_coercion(t2) < 0 as t1 < t2.
|
129
|
+
paths.each do |path|
|
130
|
+
mtime = File.mtime(path)
|
116
131
|
|
117
|
-
|
118
|
-
hash.freeze # Freeze so changes aren't accidently pushed
|
119
|
-
return if hash.empty?
|
132
|
+
next if time_now.compare_without_coercion(mtime) < 0
|
120
133
|
|
121
|
-
|
122
|
-
|
134
|
+
if max_mtime.nil? || max_mtime.compare_without_coercion(mtime) < 0
|
135
|
+
max_mtime = mtime
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
max_mtime
|
123
140
|
end
|
124
|
-
"{#{globs.join(",")}}"
|
125
|
-
end
|
126
141
|
|
127
|
-
|
128
|
-
|
129
|
-
|
142
|
+
def compile_glob(hash)
|
143
|
+
hash.freeze # Freeze so changes aren't accidentally pushed
|
144
|
+
return if hash.empty?
|
130
145
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
146
|
+
globs = hash.map do |key, value|
|
147
|
+
"#{escape(key)}/**/*#{compile_ext(value)}"
|
148
|
+
end
|
149
|
+
"{#{globs.join(",")}}"
|
150
|
+
end
|
151
|
+
|
152
|
+
def escape(key)
|
153
|
+
key.gsub(",", '\,')
|
154
|
+
end
|
155
|
+
|
156
|
+
def compile_ext(array)
|
157
|
+
array = Array(array)
|
158
|
+
return if array.empty?
|
159
|
+
".{#{array.join(",")}}"
|
160
|
+
end
|
136
161
|
end
|
137
162
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
module ForkTracker # :nodoc:
|
5
|
+
module ModernCoreExt
|
6
|
+
def _fork
|
7
|
+
pid = super
|
8
|
+
if pid == 0
|
9
|
+
ForkTracker.check!
|
10
|
+
end
|
11
|
+
pid
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module CoreExt
|
16
|
+
def fork(...)
|
17
|
+
if block_given?
|
18
|
+
super do
|
19
|
+
ForkTracker.check!
|
20
|
+
yield
|
21
|
+
end
|
22
|
+
else
|
23
|
+
unless pid = super
|
24
|
+
ForkTracker.check!
|
25
|
+
end
|
26
|
+
pid
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
module CoreExtPrivate
|
32
|
+
include CoreExt
|
33
|
+
private :fork
|
34
|
+
end
|
35
|
+
|
36
|
+
@pid = Process.pid
|
37
|
+
@callbacks = []
|
38
|
+
|
39
|
+
class << self
|
40
|
+
def check!
|
41
|
+
new_pid = Process.pid
|
42
|
+
if @pid != new_pid
|
43
|
+
@callbacks.each(&:call)
|
44
|
+
@pid = new_pid
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def hook!
|
49
|
+
if Process.respond_to?(:_fork) # Ruby 3.1+
|
50
|
+
::Process.singleton_class.prepend(ModernCoreExt)
|
51
|
+
elsif Process.respond_to?(:fork)
|
52
|
+
::Object.prepend(CoreExtPrivate) if RUBY_VERSION < "3.0"
|
53
|
+
::Kernel.prepend(CoreExtPrivate)
|
54
|
+
::Kernel.singleton_class.prepend(CoreExt)
|
55
|
+
::Process.singleton_class.prepend(CoreExt)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def after_fork(&block)
|
60
|
+
@callbacks << block
|
61
|
+
block
|
62
|
+
end
|
63
|
+
|
64
|
+
def unregister(callback)
|
65
|
+
@callbacks.delete(callback)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
ActiveSupport::ForkTracker.hook!
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveSupport
|
4
|
+
# Returns the version of the currently loaded Active Support as a <tt>Gem::Version</tt>.
|
5
|
+
def self.gem_version
|
6
|
+
Gem::Version.new VERSION::STRING
|
7
|
+
end
|
8
|
+
|
9
|
+
module VERSION
|
10
|
+
MAJOR = 7
|
11
|
+
MINOR = 0
|
12
|
+
TINY = 2
|
13
|
+
PRE = "4"
|
14
|
+
|
15
|
+
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
|
16
|
+
end
|
17
|
+
end
|
data/lib/active_support/gzip.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "zlib"
|
4
|
+
require "stringio"
|
3
5
|
|
4
6
|
module ActiveSupport
|
5
7
|
# A convenient wrapper for the zlib standard library that allows
|
@@ -9,7 +11,7 @@ module ActiveSupport
|
|
9
11
|
# # => "\x1F\x8B\b\x00o\x8D\xCDO\x00\x03K\xCE\xCF-(J-.V\xC8MU\x04\x00R>n\x83\f\x00\x00\x00"
|
10
12
|
#
|
11
13
|
# ActiveSupport::Gzip.decompress(gzip)
|
12
|
-
# # => "compress me!"
|
14
|
+
# # => "compress me!"
|
13
15
|
module Gzip
|
14
16
|
class Stream < StringIO
|
15
17
|
def initialize(*)
|
@@ -21,11 +23,11 @@ module ActiveSupport
|
|
21
23
|
|
22
24
|
# Decompresses a gzipped string.
|
23
25
|
def self.decompress(source)
|
24
|
-
Zlib::GzipReader.
|
26
|
+
Zlib::GzipReader.wrap(StringIO.new(source), &:read)
|
25
27
|
end
|
26
28
|
|
27
29
|
# Compresses a string using gzip.
|
28
|
-
def self.compress(source, level=Zlib::DEFAULT_COMPRESSION, strategy=Zlib::DEFAULT_STRATEGY)
|
30
|
+
def self.compress(source, level = Zlib::DEFAULT_COMPRESSION, strategy = Zlib::DEFAULT_STRATEGY)
|
29
31
|
output = Stream.new
|
30
32
|
gz = Zlib::GzipWriter.new(output, level, strategy)
|
31
33
|
gz.write(source)
|
@@ -1,4 +1,9 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash/keys"
|
4
|
+
require "active_support/core_ext/hash/reverse_merge"
|
5
|
+
require "active_support/core_ext/hash/except"
|
6
|
+
require "active_support/core_ext/hash/slice"
|
2
7
|
|
3
8
|
module ActiveSupport
|
4
9
|
# Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
|
@@ -39,6 +44,12 @@ module ActiveSupport
|
|
39
44
|
# rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access
|
40
45
|
#
|
41
46
|
# which may be handy.
|
47
|
+
#
|
48
|
+
# To access this class outside of Rails, require the core extension with:
|
49
|
+
#
|
50
|
+
# require "active_support/core_ext/hash/indifferent_access"
|
51
|
+
#
|
52
|
+
# which will, in turn, require this file.
|
42
53
|
class HashWithIndifferentAccess < Hash
|
43
54
|
# Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
|
44
55
|
# this class.
|
@@ -54,27 +65,18 @@ module ActiveSupport
|
|
54
65
|
self
|
55
66
|
end
|
56
67
|
|
57
|
-
def initialize(constructor =
|
58
|
-
if constructor.
|
68
|
+
def initialize(constructor = nil)
|
69
|
+
if constructor.respond_to?(:to_hash)
|
59
70
|
super()
|
60
71
|
update(constructor)
|
61
|
-
else
|
62
|
-
super(constructor)
|
63
|
-
end
|
64
|
-
end
|
65
72
|
|
66
|
-
|
67
|
-
|
68
|
-
self
|
73
|
+
hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
|
74
|
+
self.default = hash.default if hash.default
|
75
|
+
self.default_proc = hash.default_proc if hash.default_proc
|
76
|
+
elsif constructor.nil?
|
77
|
+
super()
|
69
78
|
else
|
70
|
-
super
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.new_from_hash_copying_default(hash)
|
75
|
-
hash = hash.to_hash
|
76
|
-
new(hash).tap do |new_hash|
|
77
|
-
new_hash.default = hash.default
|
79
|
+
super(constructor)
|
78
80
|
end
|
79
81
|
end
|
80
82
|
|
@@ -90,14 +92,14 @@ module ActiveSupport
|
|
90
92
|
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
91
93
|
# hash[:key] = 'value'
|
92
94
|
#
|
93
|
-
# This value can be later fetched using either +:key+ or
|
95
|
+
# This value can be later fetched using either +:key+ or <tt>'key'</tt>.
|
94
96
|
def []=(key, value)
|
95
|
-
regular_writer(convert_key(key), convert_value(value,
|
97
|
+
regular_writer(convert_key(key), convert_value(value, conversion: :assignment))
|
96
98
|
end
|
97
99
|
|
98
100
|
alias_method :store, :[]=
|
99
101
|
|
100
|
-
# Updates the receiver in-place, merging in the
|
102
|
+
# Updates the receiver in-place, merging in the hashes passed as arguments:
|
101
103
|
#
|
102
104
|
# hash_1 = ActiveSupport::HashWithIndifferentAccess.new
|
103
105
|
# hash_1[:key] = 'value'
|
@@ -107,11 +109,14 @@ module ActiveSupport
|
|
107
109
|
#
|
108
110
|
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
109
111
|
#
|
110
|
-
#
|
112
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
113
|
+
# hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 }
|
114
|
+
#
|
115
|
+
# The arguments can be either an
|
111
116
|
# <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
|
112
117
|
# In either case the merge respects the semantics of indifferent access.
|
113
118
|
#
|
114
|
-
# If the argument is a regular hash with keys +:key+ and
|
119
|
+
# If the argument is a regular hash with keys +:key+ and <tt>"key"</tt> only one
|
115
120
|
# of the values end up in the receiver, but which one is unspecified.
|
116
121
|
#
|
117
122
|
# When given a block, the value for duplicated keys will be determined
|
@@ -122,18 +127,15 @@ module ActiveSupport
|
|
122
127
|
# hash_1[:key] = 10
|
123
128
|
# hash_2['key'] = 12
|
124
129
|
# hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
|
125
|
-
def update(
|
126
|
-
if
|
127
|
-
|
130
|
+
def update(*other_hashes, &block)
|
131
|
+
if other_hashes.size == 1
|
132
|
+
update_with_single_argument(other_hashes.first, block)
|
128
133
|
else
|
129
|
-
|
130
|
-
|
131
|
-
value = yield(convert_key(key), self[key], value)
|
132
|
-
end
|
133
|
-
regular_writer(convert_key(key), convert_value(value))
|
134
|
+
other_hashes.each do |other_hash|
|
135
|
+
update_with_single_argument(other_hash, block)
|
134
136
|
end
|
135
|
-
self
|
136
137
|
end
|
138
|
+
self
|
137
139
|
end
|
138
140
|
|
139
141
|
alias_method :merge!, :update
|
@@ -152,6 +154,32 @@ module ActiveSupport
|
|
152
154
|
alias_method :has_key?, :key?
|
153
155
|
alias_method :member?, :key?
|
154
156
|
|
157
|
+
# Same as <tt>Hash#[]</tt> where the key passed as argument can be
|
158
|
+
# either a string or a symbol:
|
159
|
+
#
|
160
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
161
|
+
# counters[:foo] = 1
|
162
|
+
#
|
163
|
+
# counters['foo'] # => 1
|
164
|
+
# counters[:foo] # => 1
|
165
|
+
# counters[:zoo] # => nil
|
166
|
+
def [](key)
|
167
|
+
super(convert_key(key))
|
168
|
+
end
|
169
|
+
|
170
|
+
# Same as <tt>Hash#assoc</tt> where the key passed as argument can be
|
171
|
+
# either a string or a symbol:
|
172
|
+
#
|
173
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
174
|
+
# counters[:foo] = 1
|
175
|
+
#
|
176
|
+
# counters.assoc('foo') # => ["foo", 1]
|
177
|
+
# counters.assoc(:foo) # => ["foo", 1]
|
178
|
+
# counters.assoc(:zoo) # => nil
|
179
|
+
def assoc(key)
|
180
|
+
super(convert_key(key))
|
181
|
+
end
|
182
|
+
|
155
183
|
# Same as <tt>Hash#fetch</tt> where the key passed as argument can be
|
156
184
|
# either a string or a symbol:
|
157
185
|
#
|
@@ -160,34 +188,82 @@ module ActiveSupport
|
|
160
188
|
#
|
161
189
|
# counters.fetch('foo') # => 1
|
162
190
|
# counters.fetch(:bar, 0) # => 0
|
163
|
-
# counters.fetch(:bar) {|key| 0} # => 0
|
191
|
+
# counters.fetch(:bar) { |key| 0 } # => 0
|
164
192
|
# counters.fetch(:zoo) # => KeyError: key not found: "zoo"
|
165
193
|
def fetch(key, *extras)
|
166
194
|
super(convert_key(key), *extras)
|
167
195
|
end
|
168
196
|
|
197
|
+
# Same as <tt>Hash#dig</tt> where the key passed as argument can be
|
198
|
+
# either a string or a symbol:
|
199
|
+
#
|
200
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
201
|
+
# counters[:foo] = { bar: 1 }
|
202
|
+
#
|
203
|
+
# counters.dig('foo', 'bar') # => 1
|
204
|
+
# counters.dig(:foo, :bar) # => 1
|
205
|
+
# counters.dig(:zoo) # => nil
|
206
|
+
def dig(*args)
|
207
|
+
args[0] = convert_key(args[0]) if args.size > 0
|
208
|
+
super(*args)
|
209
|
+
end
|
210
|
+
|
211
|
+
# Same as <tt>Hash#default</tt> where the key passed as argument can be
|
212
|
+
# either a string or a symbol:
|
213
|
+
#
|
214
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new(1)
|
215
|
+
# hash.default # => 1
|
216
|
+
#
|
217
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new { |hash, key| key }
|
218
|
+
# hash.default # => nil
|
219
|
+
# hash.default('foo') # => 'foo'
|
220
|
+
# hash.default(:foo) # => 'foo'
|
221
|
+
def default(*args)
|
222
|
+
super(*args.map { |arg| convert_key(arg) })
|
223
|
+
end
|
224
|
+
|
169
225
|
# Returns an array of the values at the specified indices:
|
170
226
|
#
|
171
227
|
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
172
228
|
# hash[:a] = 'x'
|
173
229
|
# hash[:b] = 'y'
|
174
230
|
# hash.values_at('a', 'b') # => ["x", "y"]
|
175
|
-
def values_at(*
|
176
|
-
|
231
|
+
def values_at(*keys)
|
232
|
+
super(*keys.map { |key| convert_key(key) })
|
177
233
|
end
|
178
234
|
|
179
|
-
# Returns an
|
235
|
+
# Returns an array of the values at the specified indices, but also
|
236
|
+
# raises an exception when one of the keys can't be found.
|
237
|
+
#
|
238
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
239
|
+
# hash[:a] = 'x'
|
240
|
+
# hash[:b] = 'y'
|
241
|
+
# hash.fetch_values('a', 'b') # => ["x", "y"]
|
242
|
+
# hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
|
243
|
+
# hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
|
244
|
+
def fetch_values(*indices, &block)
|
245
|
+
super(*indices.map { |key| convert_key(key) }, &block)
|
246
|
+
end
|
247
|
+
|
248
|
+
# Returns a shallow copy of the hash.
|
249
|
+
#
|
250
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
|
251
|
+
# dup = hash.dup
|
252
|
+
# dup[:a][:c] = 'c'
|
253
|
+
#
|
254
|
+
# hash[:a][:c] # => "c"
|
255
|
+
# dup[:a][:c] # => "c"
|
180
256
|
def dup
|
181
257
|
self.class.new(self).tap do |new_hash|
|
182
|
-
new_hash
|
258
|
+
set_defaults(new_hash)
|
183
259
|
end
|
184
260
|
end
|
185
261
|
|
186
262
|
# This method has the same semantics of +update+, except it does not
|
187
263
|
# modify the receiver but rather returns a new hash with indifferent
|
188
264
|
# access with the result of the merge.
|
189
|
-
def merge(
|
190
|
-
|
265
|
+
def merge(*hashes, &block)
|
266
|
+
dup.update(*hashes, &block)
|
191
267
|
end
|
192
268
|
|
193
269
|
# Like +merge+ but the other way around: Merges the receiver into the
|
@@ -197,20 +273,22 @@ module ActiveSupport
|
|
197
273
|
# hash['a'] = nil
|
198
274
|
# hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
|
199
275
|
def reverse_merge(other_hash)
|
200
|
-
super(self.class.
|
276
|
+
super(self.class.new(other_hash))
|
201
277
|
end
|
278
|
+
alias_method :with_defaults, :reverse_merge
|
202
279
|
|
203
280
|
# Same semantics as +reverse_merge+ but modifies the receiver in-place.
|
204
281
|
def reverse_merge!(other_hash)
|
205
|
-
|
282
|
+
super(self.class.new(other_hash))
|
206
283
|
end
|
284
|
+
alias_method :with_defaults!, :reverse_merge!
|
207
285
|
|
208
286
|
# Replaces the contents of this hash with other_hash.
|
209
287
|
#
|
210
288
|
# h = { "a" => 100, "b" => 200 }
|
211
|
-
# h.replace({ "c" => 300, "d" => 400 })
|
289
|
+
# h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
|
212
290
|
def replace(other_hash)
|
213
|
-
super(self.class.
|
291
|
+
super(self.class.new(other_hash))
|
214
292
|
end
|
215
293
|
|
216
294
|
# Removes the specified key from the hash.
|
@@ -218,6 +296,15 @@ module ActiveSupport
|
|
218
296
|
super(convert_key(key))
|
219
297
|
end
|
220
298
|
|
299
|
+
# Returns a hash with indifferent access that includes everything except given keys.
|
300
|
+
# hash = { a: "x", b: "y", c: 10 }.with_indifferent_access
|
301
|
+
# hash.except(:a, "b") # => {c: 10}.with_indifferent_access
|
302
|
+
# hash # => { a: "x", b: "y", c: 10 }.with_indifferent_access
|
303
|
+
def except(*keys)
|
304
|
+
slice(*self.keys - keys.map { |key| convert_key(key) })
|
305
|
+
end
|
306
|
+
alias_method :without, :except
|
307
|
+
|
221
308
|
def stringify_keys!; self end
|
222
309
|
def deep_stringify_keys!; self end
|
223
310
|
def stringify_keys; dup end
|
@@ -225,48 +312,114 @@ module ActiveSupport
|
|
225
312
|
undef :symbolize_keys!
|
226
313
|
undef :deep_symbolize_keys!
|
227
314
|
def symbolize_keys; to_hash.symbolize_keys! end
|
228
|
-
|
315
|
+
alias_method :to_options, :symbolize_keys
|
316
|
+
def deep_symbolize_keys; to_hash.deep_symbolize_keys! end
|
229
317
|
def to_options!; self end
|
230
318
|
|
231
319
|
def select(*args, &block)
|
320
|
+
return to_enum(:select) unless block_given?
|
232
321
|
dup.tap { |hash| hash.select!(*args, &block) }
|
233
322
|
end
|
234
323
|
|
235
324
|
def reject(*args, &block)
|
325
|
+
return to_enum(:reject) unless block_given?
|
236
326
|
dup.tap { |hash| hash.reject!(*args, &block) }
|
237
327
|
end
|
238
328
|
|
329
|
+
def transform_values(*args, &block)
|
330
|
+
return to_enum(:transform_values) unless block_given?
|
331
|
+
dup.tap { |hash| hash.transform_values!(*args, &block) }
|
332
|
+
end
|
333
|
+
|
334
|
+
def transform_keys(*args, &block)
|
335
|
+
return to_enum(:transform_keys) unless block_given?
|
336
|
+
dup.tap { |hash| hash.transform_keys!(*args, &block) }
|
337
|
+
end
|
338
|
+
|
339
|
+
def transform_keys!
|
340
|
+
return enum_for(:transform_keys!) { size } unless block_given?
|
341
|
+
keys.each do |key|
|
342
|
+
self[yield(key)] = delete(key)
|
343
|
+
end
|
344
|
+
self
|
345
|
+
end
|
346
|
+
|
347
|
+
def slice(*keys)
|
348
|
+
keys.map! { |key| convert_key(key) }
|
349
|
+
self.class.new(super)
|
350
|
+
end
|
351
|
+
|
352
|
+
def slice!(*keys)
|
353
|
+
keys.map! { |key| convert_key(key) }
|
354
|
+
super
|
355
|
+
end
|
356
|
+
|
357
|
+
def compact
|
358
|
+
dup.tap(&:compact!)
|
359
|
+
end
|
360
|
+
|
239
361
|
# Convert to a regular hash with string keys.
|
240
362
|
def to_hash
|
241
|
-
_new_hash=
|
363
|
+
_new_hash = Hash.new
|
364
|
+
set_defaults(_new_hash)
|
365
|
+
|
242
366
|
each do |key, value|
|
243
|
-
_new_hash[
|
367
|
+
_new_hash[key] = convert_value(value, conversion: :to_hash)
|
244
368
|
end
|
245
|
-
|
369
|
+
_new_hash
|
246
370
|
end
|
247
371
|
|
248
|
-
|
249
|
-
|
250
|
-
key
|
372
|
+
private
|
373
|
+
if Symbol.method_defined?(:name)
|
374
|
+
def convert_key(key)
|
375
|
+
key.kind_of?(Symbol) ? key.name : key
|
376
|
+
end
|
377
|
+
else
|
378
|
+
def convert_key(key)
|
379
|
+
key.kind_of?(Symbol) ? key.to_s : key
|
380
|
+
end
|
251
381
|
end
|
252
382
|
|
253
|
-
def convert_value(value,
|
383
|
+
def convert_value(value, conversion: nil)
|
254
384
|
if value.is_a? Hash
|
255
|
-
if
|
385
|
+
if conversion == :to_hash
|
256
386
|
value.to_hash
|
257
387
|
else
|
258
388
|
value.nested_under_indifferent_access
|
259
389
|
end
|
260
390
|
elsif value.is_a?(Array)
|
261
|
-
|
391
|
+
if conversion != :assignment || value.frozen?
|
262
392
|
value = value.dup
|
263
393
|
end
|
264
|
-
value.map! { |e| convert_value(e,
|
394
|
+
value.map! { |e| convert_value(e, conversion: conversion) }
|
265
395
|
else
|
266
396
|
value
|
267
397
|
end
|
268
398
|
end
|
399
|
+
|
400
|
+
def set_defaults(target)
|
401
|
+
if default_proc
|
402
|
+
target.default_proc = default_proc.dup
|
403
|
+
else
|
404
|
+
target.default = default
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
def update_with_single_argument(other_hash, block)
|
409
|
+
if other_hash.is_a? HashWithIndifferentAccess
|
410
|
+
regular_update(other_hash, &block)
|
411
|
+
else
|
412
|
+
other_hash.to_hash.each_pair do |key, value|
|
413
|
+
if block && key?(key)
|
414
|
+
value = block.call(convert_key(key), self[key], value)
|
415
|
+
end
|
416
|
+
regular_writer(convert_key(key), convert_value(value))
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
269
420
|
end
|
270
421
|
end
|
271
422
|
|
423
|
+
# :stopdoc:
|
424
|
+
|
272
425
|
HashWithIndifferentAccess = ActiveSupport::HashWithIndifferentAccess
|