activesupport 4.2.11.1 → 6.0.3.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +399 -411
- data/MIT-LICENSE +2 -2
- data/README.rdoc +7 -7
- 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 +34 -6
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +58 -53
- data/lib/active_support/cache/mem_cache_store.rb +95 -91
- data/lib/active_support/cache/memory_store.rb +39 -36
- data/lib/active_support/cache/null_store.rb +11 -7
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +75 -42
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +331 -217
- data/lib/active_support/callbacks.rb +650 -592
- data/lib/active_support/concern.rb +35 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +13 -14
- data/lib/active_support/core_ext/array/access.rb +41 -1
- data/lib/active_support/core_ext/array/conversions.rb +24 -20
- 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 +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -6
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +45 -31
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -6
- data/lib/active_support/core_ext/class.rb +4 -3
- 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 +17 -14
- data/lib/active_support/core_ext/date/conversions.rb +25 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +154 -65
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -13
- 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 +37 -19
- data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -13
- data/lib/active_support/core_ext/date_time.rb +7 -5
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +114 -22
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +4 -23
- data/lib/active_support/core_ext/hash/conversions.rb +62 -41
- 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 +12 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +19 -42
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +5 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +4 -22
- data/lib/active_support/core_ext/hash.rb +10 -9
- 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 -18
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/concern.rb +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -5
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +8 -8
- 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 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -46
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +133 -30
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +44 -19
- data/lib/active_support/core_ext/module/reachable.rb +5 -7
- 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 -11
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +129 -136
- data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -23
- data/lib/active_support/core_ext/numeric.rb +5 -3
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +27 -3
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +13 -93
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +51 -20
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +10 -5
- data/lib/active_support/core_ext/object/try.rb +81 -23
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/range/compare_range.rb +76 -0
- data/lib/active_support/core_ext/range/conversions.rb +37 -15
- data/lib/active_support/core_ext/range/each.rb +18 -17
- data/lib/active_support/core_ext/range/include_range.rb +7 -21
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -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 +2 -0
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string/access.rb +16 -6
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +7 -4
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +48 -6
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +66 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +16 -7
- data/lib/active_support/core_ext/string/output_safety.rb +93 -40
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +6 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +115 -52
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/time.rb +7 -6
- data/lib/active_support/core_ext/uri.rb +6 -7
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +203 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +208 -166
- data/lib/active_support/deprecation/behaviors.rb +44 -11
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +61 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/descendants_tracker.rb +57 -9
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +53 -0
- data/lib/active_support/duration.rb +315 -40
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +100 -0
- data/lib/active_support/evented_file_update_checker.rb +234 -0
- data/lib/active_support/execution_wrapper.rb +129 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +62 -37
- data/lib/active_support/gem_version.rb +6 -4
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +129 -30
- data/lib/active_support/i18n.rb +9 -6
- data/lib/active_support/i18n_railtie.rb +50 -14
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +58 -13
- data/lib/active_support/inflector/methods.rb +159 -145
- data/lib/active_support/inflector/transliterate.rb +84 -34
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +32 -30
- data/lib/active_support/json/encoding.rb +17 -60
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +11 -43
- data/lib/active_support/lazy_load_hooks.rb +53 -20
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +44 -19
- data/lib/active_support/logger.rb +9 -23
- data/lib/active_support/logger_silence.rb +32 -14
- data/lib/active_support/logger_thread_safe_level.rb +32 -8
- data/lib/active_support/message_encryptor.rb +166 -53
- data/lib/active_support/message_verifier.rb +149 -16
- data/lib/active_support/messages/metadata.rb +72 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte/chars.rb +56 -63
- data/lib/active_support/multibyte/unicode.rb +56 -290
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +109 -22
- data/lib/active_support/notifications/instrumenter.rb +107 -16
- data/lib/active_support/notifications.rb +51 -10
- data/lib/active_support/number_helper/number_converter.rb +16 -15
- data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -15
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
- data/lib/active_support/number_helper/number_to_human_converter.rb +13 -10
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +25 -57
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +105 -68
- data/lib/active_support/option_merger.rb +24 -4
- data/lib/active_support/ordered_hash.rb +7 -5
- data/lib/active_support/ordered_options.rb +27 -5
- data/lib/active_support/parameter_filter.rb +128 -0
- data/lib/active_support/per_thread_registry.rb +9 -4
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +10 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +11 -4
- data/lib/active_support/subscriber.rb +74 -30
- data/lib/active_support/tagged_logging.rb +25 -13
- data/lib/active_support/test_case.rb +107 -44
- data/lib/active_support/testing/assertions.rb +151 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +13 -10
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +35 -26
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- data/lib/active_support/testing/parallelization.rb +134 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +43 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +84 -20
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +179 -39
- data/lib/active_support/values/time_zone.rb +203 -63
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +116 -115
- data/lib/active_support/xml_mini/libxml.rb +16 -13
- data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
- data/lib/active_support/xml_mini/nokogiri.rb +14 -12
- data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
- data/lib/active_support/xml_mini/rexml.rb +11 -9
- data/lib/active_support/xml_mini.rb +38 -46
- data/lib/active_support.rb +13 -11
- metadata +84 -26
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- 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/module/method_transplanting.rb +0 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,23 +1,29 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "set"
|
2
4
|
|
3
5
|
class Module
|
4
6
|
# Error generated by +delegate+ when a method is called on +nil+ and +allow_nil+
|
5
7
|
# option is not used.
|
6
8
|
class DelegationError < NoMethodError; end
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
RUBY_RESERVED_KEYWORDS = %w(alias and BEGIN begin break case class def defined? do
|
11
|
+
else elsif END end ensure false for if in module next nil not or redo rescue retry
|
12
|
+
return self super then true undef unless until when while yield)
|
13
|
+
DELEGATION_RESERVED_KEYWORDS = %w(_ arg args block)
|
14
|
+
DELEGATION_RESERVED_METHOD_NAMES = Set.new(
|
15
|
+
RUBY_RESERVED_KEYWORDS + DELEGATION_RESERVED_KEYWORDS
|
12
16
|
).freeze
|
13
17
|
|
14
18
|
# Provides a +delegate+ class method to easily expose contained objects'
|
15
19
|
# public methods as your own.
|
16
20
|
#
|
17
21
|
# ==== Options
|
18
|
-
# * <tt>:to</tt> - Specifies the target object
|
22
|
+
# * <tt>:to</tt> - Specifies the target object name as a symbol or string
|
19
23
|
# * <tt>:prefix</tt> - Prefixes the new method with the target name or a custom prefix
|
20
|
-
# * <tt>:allow_nil</tt> -
|
24
|
+
# * <tt>:allow_nil</tt> - If set to true, prevents a +Module::DelegationError+
|
25
|
+
# from being raised
|
26
|
+
# * <tt>:private</tt> - If set to true, changes method visibility to private
|
21
27
|
#
|
22
28
|
# The macro receives one or more method names (specified as symbols or
|
23
29
|
# strings) and the name of the target object via the <tt>:to</tt> option
|
@@ -108,19 +114,34 @@ class Module
|
|
108
114
|
# invoice.customer_name # => 'John Doe'
|
109
115
|
# invoice.customer_address # => 'Vimmersvej 13'
|
110
116
|
#
|
117
|
+
# The delegated methods are public by default.
|
118
|
+
# Pass <tt>private: true</tt> to change that.
|
119
|
+
#
|
120
|
+
# class User < ActiveRecord::Base
|
121
|
+
# has_one :profile
|
122
|
+
# delegate :first_name, to: :profile
|
123
|
+
# delegate :date_of_birth, to: :profile, private: true
|
124
|
+
#
|
125
|
+
# def age
|
126
|
+
# Date.today.year - date_of_birth.year
|
127
|
+
# end
|
128
|
+
# end
|
129
|
+
#
|
130
|
+
# User.new.first_name # => "Tomas"
|
131
|
+
# User.new.date_of_birth # => NoMethodError: private method `date_of_birth' called for #<User:0x00000008221340>
|
132
|
+
# User.new.age # => 2
|
133
|
+
#
|
111
134
|
# If the target is +nil+ and does not respond to the delegated method a
|
112
|
-
# +
|
113
|
-
#
|
114
|
-
# <tt>:allow_nil</tt> option: If the target is not +nil+, or it is and
|
115
|
-
# responds to the method, everything works as usual. But if it is +nil+ and
|
116
|
-
# does not respond to the delegated method, +nil+ is returned.
|
135
|
+
# +Module::DelegationError+ is raised. If you wish to instead return +nil+,
|
136
|
+
# use the <tt>:allow_nil</tt> option.
|
117
137
|
#
|
118
138
|
# class User < ActiveRecord::Base
|
119
139
|
# has_one :profile
|
120
140
|
# delegate :age, to: :profile
|
121
141
|
# end
|
122
142
|
#
|
123
|
-
# User.new.age
|
143
|
+
# User.new.age
|
144
|
+
# # => Module::DelegationError: User#age delegated to profile.age, but profile is nil
|
124
145
|
#
|
125
146
|
# But if not having a profile yet is fine and should not be an error
|
126
147
|
# condition:
|
@@ -147,36 +168,38 @@ class Module
|
|
147
168
|
# Foo.new("Bar").name # raises NoMethodError: undefined method `name'
|
148
169
|
#
|
149
170
|
# The target method must be public, otherwise it will raise +NoMethodError+.
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
unless options.is_a?(Hash) && to = options[:to]
|
154
|
-
raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).'
|
171
|
+
def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil)
|
172
|
+
unless to
|
173
|
+
raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter)."
|
155
174
|
end
|
156
175
|
|
157
|
-
prefix
|
158
|
-
|
159
|
-
if prefix == true && to =~ /^[^a-z_]/
|
160
|
-
raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
|
176
|
+
if prefix == true && /^[^a-z_]/.match?(to)
|
177
|
+
raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
|
161
178
|
end
|
162
179
|
|
163
180
|
method_prefix = \
|
164
181
|
if prefix
|
165
182
|
"#{prefix == true ? to : prefix}_"
|
166
183
|
else
|
167
|
-
|
184
|
+
""
|
168
185
|
end
|
169
186
|
|
170
|
-
|
171
|
-
line =
|
187
|
+
location = caller_locations(1, 1).first
|
188
|
+
file, line = location.path, location.lineno
|
172
189
|
|
173
190
|
to = to.to_s
|
174
|
-
to = "self.#{to}" if
|
191
|
+
to = "self.#{to}" if DELEGATION_RESERVED_METHOD_NAMES.include?(to)
|
175
192
|
|
176
|
-
methods.
|
193
|
+
method_names = methods.map do |method|
|
177
194
|
# Attribute writer methods only accept one argument. Makes sure []=
|
178
195
|
# methods still accept two arguments.
|
179
|
-
definition =
|
196
|
+
definition = if /[^\]]=$/.match?(method)
|
197
|
+
"arg"
|
198
|
+
elsif RUBY_VERSION >= "2.7"
|
199
|
+
"..."
|
200
|
+
else
|
201
|
+
"*args, &block"
|
202
|
+
end
|
180
203
|
|
181
204
|
# The following generated method calls the target exactly once, storing
|
182
205
|
# the returned value in a dummy variable.
|
@@ -193,7 +216,7 @@ class Module
|
|
193
216
|
" _.#{method}(#{definition})",
|
194
217
|
"end",
|
195
218
|
"end"
|
196
|
-
].join
|
219
|
+
].join ";"
|
197
220
|
else
|
198
221
|
exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
|
199
222
|
|
@@ -208,10 +231,90 @@ class Module
|
|
208
231
|
" raise",
|
209
232
|
" end",
|
210
233
|
"end"
|
211
|
-
].join
|
234
|
+
].join ";"
|
212
235
|
end
|
213
236
|
|
214
237
|
module_eval(method_def, file, line)
|
215
238
|
end
|
239
|
+
|
240
|
+
private(*method_names) if private
|
241
|
+
method_names
|
242
|
+
end
|
243
|
+
|
244
|
+
# When building decorators, a common pattern may emerge:
|
245
|
+
#
|
246
|
+
# class Partition
|
247
|
+
# def initialize(event)
|
248
|
+
# @event = event
|
249
|
+
# end
|
250
|
+
#
|
251
|
+
# def person
|
252
|
+
# detail.person || creator
|
253
|
+
# end
|
254
|
+
#
|
255
|
+
# private
|
256
|
+
# def respond_to_missing?(name, include_private = false)
|
257
|
+
# @event.respond_to?(name, include_private)
|
258
|
+
# end
|
259
|
+
#
|
260
|
+
# def method_missing(method, *args, &block)
|
261
|
+
# @event.send(method, *args, &block)
|
262
|
+
# end
|
263
|
+
# end
|
264
|
+
#
|
265
|
+
# With <tt>Module#delegate_missing_to</tt>, the above is condensed to:
|
266
|
+
#
|
267
|
+
# class Partition
|
268
|
+
# delegate_missing_to :@event
|
269
|
+
#
|
270
|
+
# def initialize(event)
|
271
|
+
# @event = event
|
272
|
+
# end
|
273
|
+
#
|
274
|
+
# def person
|
275
|
+
# detail.person || creator
|
276
|
+
# end
|
277
|
+
# end
|
278
|
+
#
|
279
|
+
# The target can be anything callable within the object, e.g. instance
|
280
|
+
# variables, methods, constants, etc.
|
281
|
+
#
|
282
|
+
# The delegated method must be public on the target, otherwise it will
|
283
|
+
# raise +NoMethodError+.
|
284
|
+
#
|
285
|
+
# The <tt>marshal_dump</tt> and <tt>_dump</tt> methods are exempt from
|
286
|
+
# delegation due to possible interference when calling
|
287
|
+
# <tt>Marshal.dump(object)</tt>, should the delegation target method
|
288
|
+
# of <tt>object</tt> add or remove instance variables.
|
289
|
+
def delegate_missing_to(target)
|
290
|
+
target = target.to_s
|
291
|
+
target = "self.#{target}" if DELEGATION_RESERVED_METHOD_NAMES.include?(target)
|
292
|
+
|
293
|
+
module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
294
|
+
def respond_to_missing?(name, include_private = false)
|
295
|
+
# It may look like an oversight, but we deliberately do not pass
|
296
|
+
# +include_private+, because they do not get delegated.
|
297
|
+
|
298
|
+
return false if name == :marshal_dump || name == :_dump
|
299
|
+
#{target}.respond_to?(name) || super
|
300
|
+
end
|
301
|
+
|
302
|
+
def method_missing(method, *args, &block)
|
303
|
+
if #{target}.respond_to?(method)
|
304
|
+
#{target}.public_send(method, *args, &block)
|
305
|
+
else
|
306
|
+
begin
|
307
|
+
super
|
308
|
+
rescue NoMethodError
|
309
|
+
if #{target}.nil?
|
310
|
+
raise DelegationError, "\#{method} delegated to #{target}, but #{target} is nil"
|
311
|
+
else
|
312
|
+
raise
|
313
|
+
end
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
ruby2_keywords(:method_missing) if respond_to?(:ruby2_keywords, true)
|
318
|
+
RUBY
|
216
319
|
end
|
217
320
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Module
|
2
4
|
# deprecate :foo
|
3
5
|
# deprecate bar: 'message'
|
@@ -13,8 +15,8 @@ class Module
|
|
13
15
|
#
|
14
16
|
# class MyLib::Deprecator
|
15
17
|
# def deprecation_warning(deprecated_method_name, message, caller_backtrace = nil)
|
16
|
-
#
|
17
|
-
#
|
18
|
+
# message = "#{deprecated_method_name} is deprecated and will be removed from MyLibrary | #{message}"
|
19
|
+
# Kernel.warn message
|
18
20
|
# end
|
19
21
|
# end
|
20
22
|
def deprecate(*method_names)
|
@@ -1,17 +1,30 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/string/filters"
|
4
|
+
require "active_support/inflector"
|
2
5
|
|
3
6
|
class Module
|
4
7
|
# Returns the name of the module containing this one.
|
5
8
|
#
|
6
|
-
# M::N.
|
7
|
-
def
|
8
|
-
if defined?
|
9
|
+
# M::N.module_parent_name # => "M"
|
10
|
+
def module_parent_name
|
11
|
+
if defined?(@parent_name)
|
9
12
|
@parent_name
|
10
13
|
else
|
11
|
-
|
14
|
+
parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
|
15
|
+
@parent_name = parent_name unless frozen?
|
16
|
+
parent_name
|
12
17
|
end
|
13
18
|
end
|
14
19
|
|
20
|
+
def parent_name
|
21
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
22
|
+
`Module#parent_name` has been renamed to `module_parent_name`.
|
23
|
+
`parent_name` is deprecated and will be removed in Rails 6.1.
|
24
|
+
MSG
|
25
|
+
module_parent_name
|
26
|
+
end
|
27
|
+
|
15
28
|
# Returns the module which contains this one according to its name.
|
16
29
|
#
|
17
30
|
# module M
|
@@ -20,15 +33,23 @@ class Module
|
|
20
33
|
# end
|
21
34
|
# X = M::N
|
22
35
|
#
|
23
|
-
# M::N.
|
24
|
-
# X.
|
36
|
+
# M::N.module_parent # => M
|
37
|
+
# X.module_parent # => M
|
25
38
|
#
|
26
39
|
# The parent of top-level and anonymous modules is Object.
|
27
40
|
#
|
28
|
-
# M.
|
29
|
-
# Module.new.
|
41
|
+
# M.module_parent # => Object
|
42
|
+
# Module.new.module_parent # => Object
|
43
|
+
def module_parent
|
44
|
+
module_parent_name ? ActiveSupport::Inflector.constantize(module_parent_name) : Object
|
45
|
+
end
|
46
|
+
|
30
47
|
def parent
|
31
|
-
|
48
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
49
|
+
`Module#parent` has been renamed to `module_parent`.
|
50
|
+
`parent` is deprecated and will be removed in Rails 6.1.
|
51
|
+
MSG
|
52
|
+
module_parent
|
32
53
|
end
|
33
54
|
|
34
55
|
# Returns all the parents of this module according to its name, ordered from
|
@@ -40,15 +61,15 @@ class Module
|
|
40
61
|
# end
|
41
62
|
# X = M::N
|
42
63
|
#
|
43
|
-
# M.
|
44
|
-
# M::N.
|
45
|
-
# X.
|
46
|
-
def
|
64
|
+
# M.module_parents # => [Object]
|
65
|
+
# M::N.module_parents # => [M, Object]
|
66
|
+
# X.module_parents # => [M, Object]
|
67
|
+
def module_parents
|
47
68
|
parents = []
|
48
|
-
if
|
49
|
-
parts =
|
69
|
+
if module_parent_name
|
70
|
+
parts = module_parent_name.split("::")
|
50
71
|
until parts.empty?
|
51
|
-
parents << ActiveSupport::Inflector.constantize(parts *
|
72
|
+
parents << ActiveSupport::Inflector.constantize(parts * "::")
|
52
73
|
parts.pop
|
53
74
|
end
|
54
75
|
end
|
@@ -56,7 +77,11 @@ class Module
|
|
56
77
|
parents
|
57
78
|
end
|
58
79
|
|
59
|
-
def
|
60
|
-
|
80
|
+
def parents
|
81
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
82
|
+
`Module#parents` has been renamed to `module_parents`.
|
83
|
+
`parents` is deprecated and will be removed in Rails 6.1.
|
84
|
+
MSG
|
85
|
+
module_parents
|
61
86
|
end
|
62
87
|
end
|
@@ -1,8 +1,6 @@
|
|
1
|
-
|
2
|
-
require 'active_support/core_ext/string/inflections'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
3
|
+
require "active_support/core_ext/module/anonymous"
|
4
|
+
require "active_support/core_ext/string/inflections"
|
5
|
+
|
6
|
+
ActiveSupport::Deprecation.warn("reachable is deprecated and will be removed from the framework.")
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Module
|
4
|
+
# Marks the named method as intended to be redefined, if it exists.
|
5
|
+
# Suppresses the Ruby method redefinition warning. Prefer
|
6
|
+
# #redefine_method where possible.
|
7
|
+
def silence_redefinition_of_method(method)
|
8
|
+
if method_defined?(method) || private_method_defined?(method)
|
9
|
+
# This suppresses the "method redefined" warning; the self-alias
|
10
|
+
# looks odd, but means we don't need to generate a unique name
|
11
|
+
alias_method method, method
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Replaces the existing method definition, if there is one, with the passed
|
16
|
+
# block as its body.
|
17
|
+
def redefine_method(method, &block)
|
18
|
+
visibility = method_visibility(method)
|
19
|
+
silence_redefinition_of_method(method)
|
20
|
+
define_method(method, &block)
|
21
|
+
send(visibility, method)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Replaces the existing singleton method definition, if there is one, with
|
25
|
+
# the passed block as its body.
|
26
|
+
def redefine_singleton_method(method, &block)
|
27
|
+
singleton_class.redefine_method(method, &block)
|
28
|
+
end
|
29
|
+
|
30
|
+
def method_visibility(method) # :nodoc:
|
31
|
+
case
|
32
|
+
when private_method_defined?(method)
|
33
|
+
:private
|
34
|
+
when protected_method_defined?(method)
|
35
|
+
:protected
|
36
|
+
else
|
37
|
+
:public
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,12 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/redefine_method"
|
4
|
+
|
1
5
|
class Module
|
6
|
+
# Removes the named method, if it exists.
|
2
7
|
def remove_possible_method(method)
|
3
8
|
if method_defined?(method) || private_method_defined?(method)
|
4
9
|
undef_method(method)
|
5
10
|
end
|
6
11
|
end
|
7
12
|
|
8
|
-
|
9
|
-
|
10
|
-
|
13
|
+
# Removes the named singleton method, if it exists.
|
14
|
+
def remove_possible_singleton_method(method)
|
15
|
+
singleton_class.remove_possible_method(method)
|
11
16
|
end
|
12
17
|
end
|
@@ -1,11 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/aliasing"
|
4
|
+
require "active_support/core_ext/module/introspection"
|
5
|
+
require "active_support/core_ext/module/anonymous"
|
6
|
+
require "active_support/core_ext/module/attribute_accessors"
|
7
|
+
require "active_support/core_ext/module/attribute_accessors_per_thread"
|
8
|
+
require "active_support/core_ext/module/attr_internal"
|
9
|
+
require "active_support/core_ext/module/concerning"
|
10
|
+
require "active_support/core_ext/module/delegation"
|
11
|
+
require "active_support/core_ext/module/deprecation"
|
12
|
+
require "active_support/core_ext/module/redefine_method"
|
13
|
+
require "active_support/core_ext/module/remove_method"
|
@@ -1,16 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class NameError
|
2
4
|
# Extract the name of the missing constant from the exception message.
|
5
|
+
#
|
6
|
+
# begin
|
7
|
+
# HelloWorld
|
8
|
+
# rescue NameError => e
|
9
|
+
# e.missing_name
|
10
|
+
# end
|
11
|
+
# # => "HelloWorld"
|
3
12
|
def missing_name
|
13
|
+
# Since ruby v2.3.0 `did_you_mean` gem is loaded by default.
|
14
|
+
# It extends NameError#message with spell corrections which are SLOW.
|
15
|
+
# We should use original_message message instead.
|
16
|
+
message = respond_to?(:original_message) ? original_message : self.message
|
17
|
+
|
4
18
|
if /undefined local variable or method/ !~ message
|
5
19
|
$1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ message
|
6
20
|
end
|
7
21
|
end
|
8
22
|
|
9
23
|
# Was this exception raised because the given name was missing?
|
24
|
+
#
|
25
|
+
# begin
|
26
|
+
# HelloWorld
|
27
|
+
# rescue NameError => e
|
28
|
+
# e.missing_name?("HelloWorld")
|
29
|
+
# end
|
30
|
+
# # => true
|
10
31
|
def missing_name?(name)
|
11
32
|
if name.is_a? Symbol
|
12
|
-
|
13
|
-
last_name == name.to_s
|
33
|
+
self.name == name
|
14
34
|
else
|
15
35
|
missing_name == name.to_s
|
16
36
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class Numeric
|
2
4
|
KILOBYTE = 1024
|
3
5
|
MEGABYTE = KILOBYTE * 1024
|
@@ -7,36 +9,56 @@ class Numeric
|
|
7
9
|
EXABYTE = PETABYTE * 1024
|
8
10
|
|
9
11
|
# Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
|
12
|
+
#
|
13
|
+
# 2.bytes # => 2
|
10
14
|
def bytes
|
11
15
|
self
|
12
16
|
end
|
13
17
|
alias :byte :bytes
|
14
18
|
|
19
|
+
# Returns the number of bytes equivalent to the kilobytes provided.
|
20
|
+
#
|
21
|
+
# 2.kilobytes # => 2048
|
15
22
|
def kilobytes
|
16
23
|
self * KILOBYTE
|
17
24
|
end
|
18
25
|
alias :kilobyte :kilobytes
|
19
26
|
|
27
|
+
# Returns the number of bytes equivalent to the megabytes provided.
|
28
|
+
#
|
29
|
+
# 2.megabytes # => 2_097_152
|
20
30
|
def megabytes
|
21
31
|
self * MEGABYTE
|
22
32
|
end
|
23
33
|
alias :megabyte :megabytes
|
24
34
|
|
35
|
+
# Returns the number of bytes equivalent to the gigabytes provided.
|
36
|
+
#
|
37
|
+
# 2.gigabytes # => 2_147_483_648
|
25
38
|
def gigabytes
|
26
39
|
self * GIGABYTE
|
27
40
|
end
|
28
41
|
alias :gigabyte :gigabytes
|
29
42
|
|
43
|
+
# Returns the number of bytes equivalent to the terabytes provided.
|
44
|
+
#
|
45
|
+
# 2.terabytes # => 2_199_023_255_552
|
30
46
|
def terabytes
|
31
47
|
self * TERABYTE
|
32
48
|
end
|
33
49
|
alias :terabyte :terabytes
|
34
50
|
|
51
|
+
# Returns the number of bytes equivalent to the petabytes provided.
|
52
|
+
#
|
53
|
+
# 2.petabytes # => 2_251_799_813_685_248
|
35
54
|
def petabytes
|
36
55
|
self * PETABYTE
|
37
56
|
end
|
38
57
|
alias :petabyte :petabytes
|
39
58
|
|
59
|
+
# Returns the number of bytes equivalent to the exabytes provided.
|
60
|
+
#
|
61
|
+
# 2.exabytes # => 2_305_843_009_213_693_952
|
40
62
|
def exabytes
|
41
63
|
self * EXABYTE
|
42
64
|
end
|