activesupport 1.2.4 → 8.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +505 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +40 -0
- data/lib/active_support/actionable_error.rb +50 -0
- data/lib/active_support/all.rb +5 -0
- data/lib/active_support/array_inquirer.rb +50 -0
- data/lib/active_support/backtrace_cleaner.rb +234 -0
- data/lib/active_support/benchmark.rb +21 -0
- data/lib/active_support/benchmarkable.rb +53 -0
- data/lib/active_support/broadcast_logger.rb +238 -0
- data/lib/active_support/builder.rb +8 -0
- data/lib/active_support/cache/coder.rb +153 -0
- data/lib/active_support/cache/entry.rb +134 -0
- data/lib/active_support/cache/file_store.rb +244 -0
- data/lib/active_support/cache/mem_cache_store.rb +288 -0
- data/lib/active_support/cache/memory_store.rb +264 -0
- data/lib/active_support/cache/null_store.rb +62 -0
- data/lib/active_support/cache/redis_cache_store.rb +498 -0
- data/lib/active_support/cache/serializer_with_fallback.rb +152 -0
- data/lib/active_support/cache/strategy/local_cache.rb +246 -0
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
- data/lib/active_support/cache.rb +1170 -0
- data/lib/active_support/callbacks.rb +960 -0
- data/lib/active_support/class_attribute.rb +33 -0
- data/lib/active_support/code_generator.rb +79 -0
- data/lib/active_support/concern.rb +217 -0
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
- data/lib/active_support/concurrency/null_lock.rb +13 -0
- data/lib/active_support/concurrency/share_lock.rb +225 -0
- data/lib/active_support/concurrency/thread_monitor.rb +55 -0
- data/lib/active_support/configurable.rb +193 -0
- data/lib/active_support/configuration_file.rb +60 -0
- data/lib/active_support/continuous_integration.rb +145 -0
- data/lib/active_support/core_ext/array/access.rb +100 -0
- data/lib/active_support/core_ext/array/conversions.rb +209 -26
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +31 -0
- data/lib/active_support/core_ext/array/grouping.rb +109 -0
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/wrap.rb +48 -0
- data/lib/active_support/core_ext/array.rb +8 -4
- data/lib/active_support/core_ext/benchmark.rb +6 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
- data/lib/active_support/core_ext/big_decimal.rb +3 -0
- data/lib/active_support/core_ext/class/attribute.rb +137 -0
- data/lib/active_support/core_ext/class/attribute_accessors.rb +6 -0
- data/lib/active_support/core_ext/class/subclasses.rb +24 -0
- data/lib/active_support/core_ext/class.rb +4 -0
- data/lib/active_support/core_ext/date/acts_like.rb +10 -0
- data/lib/active_support/core_ext/date/blank.rb +18 -0
- data/lib/active_support/core_ext/date/calculations.rb +161 -0
- data/lib/active_support/core_ext/date/conversions.rb +95 -28
- data/lib/active_support/core_ext/date/zones.rb +8 -0
- data/lib/active_support/core_ext/date.rb +6 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +374 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +23 -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 +16 -0
- data/lib/active_support/core_ext/date_time/blank.rb +18 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +215 -0
- data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +108 -0
- data/lib/active_support/core_ext/date_time.rb +7 -0
- data/lib/active_support/core_ext/digest/uuid.rb +76 -0
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +277 -7
- data/lib/active_support/core_ext/erb/util.rb +201 -0
- data/lib/active_support/core_ext/file/atomic.rb +72 -0
- data/lib/active_support/core_ext/file.rb +3 -0
- data/lib/active_support/core_ext/hash/conversions.rb +262 -0
- data/lib/active_support/core_ext/hash/deep_merge.rb +43 -0
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +12 -0
- data/lib/active_support/core_ext/hash/indifferent_access.rb +19 -55
- data/lib/active_support/core_ext/hash/keys.rb +134 -44
- data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -22
- data/lib/active_support/core_ext/hash/slice.rb +27 -0
- data/lib/active_support/core_ext/hash.rb +9 -8
- data/lib/active_support/core_ext/integer/inflections.rb +29 -13
- data/lib/active_support/core_ext/integer/multiple.rb +12 -0
- data/lib/active_support/core_ext/integer/time.rb +22 -0
- data/lib/active_support/core_ext/integer.rb +4 -6
- data/lib/active_support/core_ext/kernel/concern.rb +14 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +45 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +8 -0
- data/lib/active_support/core_ext/kernel.rb +4 -78
- data/lib/active_support/core_ext/load_error.rb +6 -35
- data/lib/active_support/core_ext/module/aliasing.rb +31 -0
- data/lib/active_support/core_ext/module/anonymous.rb +30 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +48 -0
- data/lib/active_support/core_ext/module/attribute_accessors.rb +214 -0
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +175 -0
- data/lib/active_support/core_ext/module/concerning.rb +140 -0
- data/lib/active_support/core_ext/module/delegation.rb +225 -0
- data/lib/active_support/core_ext/module/deprecation.rb +25 -0
- data/lib/active_support/core_ext/module/introspection.rb +65 -0
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +17 -0
- data/lib/active_support/core_ext/module.rb +13 -0
- data/lib/active_support/core_ext/name_error.rb +59 -0
- data/lib/active_support/core_ext/numeric/bytes.rb +73 -42
- data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
- data/lib/active_support/core_ext/numeric/time.rb +64 -57
- data/lib/active_support/core_ext/numeric.rb +4 -6
- data/lib/active_support/core_ext/object/acts_like.rb +45 -0
- data/lib/active_support/core_ext/object/blank.rb +199 -0
- data/lib/active_support/core_ext/object/conversions.rb +6 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +71 -0
- data/lib/active_support/core_ext/object/duplicable.rb +69 -0
- data/lib/active_support/core_ext/object/inclusion.rb +37 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +32 -0
- data/lib/active_support/core_ext/object/json.rb +267 -0
- data/lib/active_support/core_ext/object/to_param.rb +3 -0
- data/lib/active_support/core_ext/object/to_query.rb +93 -0
- data/lib/active_support/core_ext/object/try.rb +158 -0
- data/lib/active_support/core_ext/object/with.rb +46 -0
- data/lib/active_support/core_ext/object/with_options.rb +101 -0
- data/lib/active_support/core_ext/object.rb +17 -0
- data/lib/active_support/core_ext/pathname/blank.rb +20 -0
- data/lib/active_support/core_ext/pathname/existence.rb +23 -0
- data/lib/active_support/core_ext/pathname.rb +4 -0
- data/lib/active_support/core_ext/range/compare_range.rb +57 -0
- data/lib/active_support/core_ext/range/conversions.rb +58 -17
- data/lib/active_support/core_ext/range/overlap.rb +40 -0
- data/lib/active_support/core_ext/range/sole.rb +17 -0
- data/lib/active_support/core_ext/range.rb +5 -4
- data/lib/active_support/core_ext/regexp.rb +14 -0
- data/lib/active_support/core_ext/securerandom.rb +57 -0
- data/lib/active_support/core_ext/string/access.rb +93 -56
- data/lib/active_support/core_ext/string/behavior.rb +8 -0
- data/lib/active_support/core_ext/string/conversions.rb +57 -16
- data/lib/active_support/core_ext/string/exclude.rb +13 -0
- data/lib/active_support/core_ext/string/filters.rb +151 -0
- data/lib/active_support/core_ext/string/indent.rb +45 -0
- data/lib/active_support/core_ext/string/inflections.rb +297 -54
- data/lib/active_support/core_ext/string/inquiry.rb +16 -0
- data/lib/active_support/core_ext/string/multibyte.rb +67 -0
- data/lib/active_support/core_ext/string/output_safety.rb +235 -0
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -18
- data/lib/active_support/core_ext/string/strip.rb +27 -0
- data/lib/active_support/core_ext/string/zones.rb +16 -0
- data/lib/active_support/core_ext/string.rb +14 -10
- 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/thread/backtrace/location.rb +7 -0
- data/lib/active_support/core_ext/time/acts_like.rb +10 -0
- data/lib/active_support/core_ext/time/calculations.rb +358 -153
- data/lib/active_support/core_ext/time/compatibility.rb +15 -0
- data/lib/active_support/core_ext/time/conversions.rb +69 -30
- data/lib/active_support/core_ext/time/zones.rb +97 -0
- data/lib/active_support/core_ext/time.rb +6 -6
- data/lib/active_support/core_ext.rb +5 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +243 -0
- data/lib/active_support/deep_mergeable.rb +53 -0
- data/lib/active_support/delegation.rb +183 -0
- data/lib/active_support/dependencies/autoload.rb +72 -0
- data/lib/active_support/dependencies/interlock.rb +55 -0
- data/lib/active_support/dependencies/require_dependency.rb +28 -0
- data/lib/active_support/dependencies.rb +84 -222
- data/lib/active_support/deprecation/behaviors.rb +148 -0
- data/lib/active_support/deprecation/constant_accessor.rb +74 -0
- data/lib/active_support/deprecation/deprecators.rb +104 -0
- data/lib/active_support/deprecation/disallowed.rb +54 -0
- data/lib/active_support/deprecation/method_wrappers.rb +68 -0
- data/lib/active_support/deprecation/proxy_wrappers.rb +189 -0
- data/lib/active_support/deprecation/reporting.rb +162 -0
- data/lib/active_support/deprecation.rb +81 -0
- data/lib/active_support/deprecator.rb +7 -0
- data/lib/active_support/descendants_tracker.rb +112 -0
- 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 +64 -0
- data/lib/active_support/duration.rb +524 -0
- data/lib/active_support/editor.rb +70 -0
- data/lib/active_support/encrypted_configuration.rb +126 -0
- data/lib/active_support/encrypted_file.rb +133 -0
- data/lib/active_support/environment_inquirer.rb +40 -0
- data/lib/active_support/error_reporter/test_helper.rb +15 -0
- data/lib/active_support/error_reporter.rb +318 -0
- data/lib/active_support/event_reporter/test_helper.rb +32 -0
- data/lib/active_support/event_reporter.rb +592 -0
- data/lib/active_support/evented_file_update_checker.rb +185 -0
- data/lib/active_support/execution_context/test_helper.rb +13 -0
- data/lib/active_support/execution_context.rb +110 -0
- data/lib/active_support/execution_wrapper.rb +150 -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 +166 -0
- data/lib/active_support/fork_tracker.rb +43 -0
- data/lib/active_support/gem_version.rb +17 -0
- data/lib/active_support/gzip.rb +41 -0
- data/lib/active_support/hash_with_indifferent_access.rb +464 -0
- data/lib/active_support/html_safe_translation.rb +56 -0
- data/lib/active_support/i18n.rb +17 -0
- data/lib/active_support/i18n_railtie.rb +140 -0
- data/lib/active_support/inflections.rb +68 -49
- data/lib/active_support/inflector/inflections.rb +290 -0
- data/lib/active_support/inflector/methods.rb +387 -0
- data/lib/active_support/inflector/transliterate.rb +147 -0
- data/lib/active_support/inflector.rb +7 -164
- data/lib/active_support/isolated_execution_state.rb +76 -0
- data/lib/active_support/json/decoding.rb +78 -0
- data/lib/active_support/json/encoding.rb +256 -0
- data/lib/active_support/json.rb +4 -0
- data/lib/active_support/key_generator.rb +66 -0
- data/lib/active_support/lazy_load_hooks.rb +107 -0
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +141 -0
- data/lib/active_support/log_subscriber/test_helper.rb +106 -0
- data/lib/active_support/log_subscriber.rb +188 -0
- data/lib/active_support/logger.rb +55 -0
- data/lib/active_support/logger_silence.rb +21 -0
- data/lib/active_support/logger_thread_safe_level.rb +50 -0
- data/lib/active_support/message_encryptor.rb +374 -0
- data/lib/active_support/message_encryptors.rb +193 -0
- data/lib/active_support/message_pack/cache_serializer.rb +23 -0
- data/lib/active_support/message_pack/extensions.rb +310 -0
- data/lib/active_support/message_pack/serializer.rb +63 -0
- data/lib/active_support/message_pack.rb +50 -0
- data/lib/active_support/message_verifier.rb +377 -0
- data/lib/active_support/message_verifiers.rb +189 -0
- data/lib/active_support/messages/codec.rb +65 -0
- data/lib/active_support/messages/metadata.rb +146 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotation_coordinator.rb +102 -0
- data/lib/active_support/messages/rotator.rb +69 -0
- data/lib/active_support/messages/serializer_with_fallback.rb +158 -0
- data/lib/active_support/multibyte/chars.rb +188 -0
- data/lib/active_support/multibyte/unicode.rb +42 -0
- data/lib/active_support/multibyte.rb +27 -0
- data/lib/active_support/notifications/fanout.rb +467 -0
- data/lib/active_support/notifications/instrumenter.rb +240 -0
- data/lib/active_support/notifications.rb +281 -0
- data/lib/active_support/number_helper/number_converter.rb +190 -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 +60 -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 +479 -0
- data/lib/active_support/option_merger.rb +38 -0
- data/lib/active_support/ordered_hash.rb +50 -0
- data/lib/active_support/ordered_options.rb +141 -25
- data/lib/active_support/parameter_filter.rb +157 -0
- data/lib/active_support/rails.rb +26 -0
- data/lib/active_support/railtie.rb +180 -0
- data/lib/active_support/reloader.rb +138 -0
- data/lib/active_support/rescuable.rb +176 -0
- data/lib/active_support/secure_compare_rotator.rb +58 -0
- data/lib/active_support/security_utils.rb +38 -0
- data/lib/active_support/string_inquirer.rb +35 -0
- data/lib/active_support/structured_event_subscriber.rb +99 -0
- data/lib/active_support/subscriber.rb +141 -0
- data/lib/active_support/syntax_error_proxy.rb +67 -0
- data/lib/active_support/tagged_logging.rb +157 -0
- data/lib/active_support/test_case.rb +365 -0
- data/lib/active_support/testing/assertions.rb +369 -0
- data/lib/active_support/testing/autorun.rb +10 -0
- data/lib/active_support/testing/constant_lookup.rb +51 -0
- data/lib/active_support/testing/constant_stubbing.rb +54 -0
- data/lib/active_support/testing/declarative.rb +28 -0
- data/lib/active_support/testing/deprecation.rb +82 -0
- data/lib/active_support/testing/error_reporter_assertions.rb +124 -0
- data/lib/active_support/testing/event_reporter_assertions.rb +227 -0
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +121 -0
- data/lib/active_support/testing/method_call_assertions.rb +69 -0
- data/lib/active_support/testing/notification_assertions.rb +92 -0
- data/lib/active_support/testing/parallelization/server.rb +98 -0
- data/lib/active_support/testing/parallelization/worker.rb +107 -0
- data/lib/active_support/testing/parallelization.rb +79 -0
- data/lib/active_support/testing/parallelize_executor.rb +81 -0
- data/lib/active_support/testing/setup_and_teardown.rb +57 -0
- data/lib/active_support/testing/stream.rb +41 -0
- data/lib/active_support/testing/tagged_logging.rb +27 -0
- data/lib/active_support/testing/tests_without_assertions.rb +19 -0
- data/lib/active_support/testing/time_helpers.rb +273 -0
- data/lib/active_support/time.rb +20 -0
- data/lib/active_support/time_with_zone.rb +613 -0
- data/lib/active_support/values/time_zone.rb +599 -158
- data/lib/active_support/version.rb +7 -6
- data/lib/active_support/xml_mini/jdom.rb +175 -0
- data/lib/active_support/xml_mini/libxml.rb +80 -0
- data/lib/active_support/xml_mini/libxmlsax.rb +83 -0
- data/lib/active_support/xml_mini/nokogiri.rb +83 -0
- data/lib/active_support/xml_mini/nokogirisax.rb +86 -0
- data/lib/active_support/xml_mini/rexml.rb +137 -0
- data/lib/active_support/xml_mini.rb +212 -0
- data/lib/active_support.rb +122 -10
- metadata +524 -93
- data/CHANGELOG +0 -283
- data/lib/active_support/binding_of_caller.rb +0 -84
- data/lib/active_support/breakpoint.rb +0 -523
- data/lib/active_support/class_attribute_accessors.rb +0 -57
- data/lib/active_support/class_inheritable_attributes.rb +0 -117
- data/lib/active_support/clean_logger.rb +0 -36
- data/lib/active_support/core_ext/blank.rb +0 -38
- data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -14
- data/lib/active_support/core_ext/cgi.rb +0 -5
- data/lib/active_support/core_ext/exception.rb +0 -29
- data/lib/active_support/core_ext/integer/even_odd.rb +0 -24
- data/lib/active_support/core_ext/object_and_class.rb +0 -44
- data/lib/active_support/module_attribute_accessors.rb +0 -57
- data/lib/active_support/whiny_nil.rb +0 -38
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Module
|
|
4
|
+
require "active_support/delegation"
|
|
5
|
+
DelegationError = ActiveSupport::DelegationError # :nodoc:
|
|
6
|
+
|
|
7
|
+
# Provides a +delegate+ class method to easily expose contained objects'
|
|
8
|
+
# public methods as your own.
|
|
9
|
+
#
|
|
10
|
+
# ==== Options
|
|
11
|
+
# * <tt>:to</tt> - Specifies the target object name as a symbol or string
|
|
12
|
+
# * <tt>:prefix</tt> - Prefixes the new method with the target name or a custom prefix
|
|
13
|
+
# * <tt>:allow_nil</tt> - If set to true, prevents a +ActiveSupport::DelegationError+
|
|
14
|
+
# from being raised
|
|
15
|
+
# * <tt>:private</tt> - If set to true, changes method visibility to private
|
|
16
|
+
#
|
|
17
|
+
# The macro receives one or more method names (specified as symbols or
|
|
18
|
+
# strings) and the name of the target object via the <tt>:to</tt> option
|
|
19
|
+
# (also a symbol or string).
|
|
20
|
+
#
|
|
21
|
+
# Delegation is particularly useful with Active Record associations:
|
|
22
|
+
#
|
|
23
|
+
# class Greeter < ActiveRecord::Base
|
|
24
|
+
# def hello
|
|
25
|
+
# 'hello'
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# def goodbye
|
|
29
|
+
# 'goodbye'
|
|
30
|
+
# end
|
|
31
|
+
# end
|
|
32
|
+
#
|
|
33
|
+
# class Foo < ActiveRecord::Base
|
|
34
|
+
# belongs_to :greeter
|
|
35
|
+
# delegate :hello, to: :greeter
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# Foo.new.hello # => "hello"
|
|
39
|
+
# Foo.new.goodbye # => NoMethodError: undefined method `goodbye' for #<Foo:0x1af30c>
|
|
40
|
+
#
|
|
41
|
+
# Multiple delegates to the same target are allowed:
|
|
42
|
+
#
|
|
43
|
+
# class Foo < ActiveRecord::Base
|
|
44
|
+
# belongs_to :greeter
|
|
45
|
+
# delegate :hello, :goodbye, to: :greeter
|
|
46
|
+
# end
|
|
47
|
+
#
|
|
48
|
+
# Foo.new.goodbye # => "goodbye"
|
|
49
|
+
#
|
|
50
|
+
# Methods can be delegated to instance variables, class variables, or constants
|
|
51
|
+
# by providing them as a symbols:
|
|
52
|
+
#
|
|
53
|
+
# class Foo
|
|
54
|
+
# CONSTANT_ARRAY = [0,1,2,3]
|
|
55
|
+
# @@class_array = [4,5,6,7]
|
|
56
|
+
#
|
|
57
|
+
# def initialize
|
|
58
|
+
# @instance_array = [8,9,10,11]
|
|
59
|
+
# end
|
|
60
|
+
# delegate :sum, to: :CONSTANT_ARRAY
|
|
61
|
+
# delegate :min, to: :@@class_array
|
|
62
|
+
# delegate :max, to: :@instance_array
|
|
63
|
+
# end
|
|
64
|
+
#
|
|
65
|
+
# Foo.new.sum # => 6
|
|
66
|
+
# Foo.new.min # => 4
|
|
67
|
+
# Foo.new.max # => 11
|
|
68
|
+
#
|
|
69
|
+
# It's also possible to delegate a method to the class by using +:class+:
|
|
70
|
+
#
|
|
71
|
+
# class Foo
|
|
72
|
+
# def self.hello
|
|
73
|
+
# "world"
|
|
74
|
+
# end
|
|
75
|
+
#
|
|
76
|
+
# delegate :hello, to: :class
|
|
77
|
+
# end
|
|
78
|
+
#
|
|
79
|
+
# Foo.new.hello # => "world"
|
|
80
|
+
#
|
|
81
|
+
# Delegates can optionally be prefixed using the <tt>:prefix</tt> option. If the value
|
|
82
|
+
# is <tt>true</tt>, the delegate methods are prefixed with the name of the object being
|
|
83
|
+
# delegated to.
|
|
84
|
+
#
|
|
85
|
+
# Person = Struct.new(:name, :address)
|
|
86
|
+
#
|
|
87
|
+
# class Invoice < Struct.new(:client)
|
|
88
|
+
# delegate :name, :address, to: :client, prefix: true
|
|
89
|
+
# end
|
|
90
|
+
#
|
|
91
|
+
# john_doe = Person.new('John Doe', 'Vimmersvej 13')
|
|
92
|
+
# invoice = Invoice.new(john_doe)
|
|
93
|
+
# invoice.client_name # => "John Doe"
|
|
94
|
+
# invoice.client_address # => "Vimmersvej 13"
|
|
95
|
+
#
|
|
96
|
+
# It is also possible to supply a custom prefix.
|
|
97
|
+
#
|
|
98
|
+
# class Invoice < Struct.new(:client)
|
|
99
|
+
# delegate :name, :address, to: :client, prefix: :customer
|
|
100
|
+
# end
|
|
101
|
+
#
|
|
102
|
+
# invoice = Invoice.new(john_doe)
|
|
103
|
+
# invoice.customer_name # => 'John Doe'
|
|
104
|
+
# invoice.customer_address # => 'Vimmersvej 13'
|
|
105
|
+
#
|
|
106
|
+
# The delegated methods are public by default.
|
|
107
|
+
# Pass <tt>private: true</tt> to change that.
|
|
108
|
+
#
|
|
109
|
+
# class User < ActiveRecord::Base
|
|
110
|
+
# has_one :profile
|
|
111
|
+
# delegate :first_name, to: :profile
|
|
112
|
+
# delegate :date_of_birth, to: :profile, private: true
|
|
113
|
+
#
|
|
114
|
+
# def age
|
|
115
|
+
# Date.today.year - date_of_birth.year
|
|
116
|
+
# end
|
|
117
|
+
# end
|
|
118
|
+
#
|
|
119
|
+
# User.new.first_name # => "Tomas"
|
|
120
|
+
# User.new.date_of_birth # => NoMethodError: private method `date_of_birth' called for #<User:0x00000008221340>
|
|
121
|
+
# User.new.age # => 2
|
|
122
|
+
#
|
|
123
|
+
# If the target is +nil+ and does not respond to the delegated method a
|
|
124
|
+
# +ActiveSupport::DelegationError+ is raised. If you wish to instead return +nil+,
|
|
125
|
+
# use the <tt>:allow_nil</tt> option.
|
|
126
|
+
#
|
|
127
|
+
# class User < ActiveRecord::Base
|
|
128
|
+
# has_one :profile
|
|
129
|
+
# delegate :age, to: :profile
|
|
130
|
+
# end
|
|
131
|
+
#
|
|
132
|
+
# User.new.age
|
|
133
|
+
# # => ActiveSupport::DelegationError: User#age delegated to profile.age, but profile is nil
|
|
134
|
+
#
|
|
135
|
+
# But if not having a profile yet is fine and should not be an error
|
|
136
|
+
# condition:
|
|
137
|
+
#
|
|
138
|
+
# class User < ActiveRecord::Base
|
|
139
|
+
# has_one :profile
|
|
140
|
+
# delegate :age, to: :profile, allow_nil: true
|
|
141
|
+
# end
|
|
142
|
+
#
|
|
143
|
+
# User.new.age # nil
|
|
144
|
+
#
|
|
145
|
+
# Note that if the target is not +nil+ then the call is attempted regardless of the
|
|
146
|
+
# <tt>:allow_nil</tt> option, and thus an exception is still raised if said object
|
|
147
|
+
# does not respond to the method:
|
|
148
|
+
#
|
|
149
|
+
# class Foo
|
|
150
|
+
# def initialize(bar)
|
|
151
|
+
# @bar = bar
|
|
152
|
+
# end
|
|
153
|
+
#
|
|
154
|
+
# delegate :name, to: :@bar, allow_nil: true
|
|
155
|
+
# end
|
|
156
|
+
#
|
|
157
|
+
# Foo.new("Bar").name # raises NoMethodError: undefined method `name'
|
|
158
|
+
#
|
|
159
|
+
# The target method must be public, otherwise it will raise +NoMethodError+.
|
|
160
|
+
def delegate(*methods, to: nil, prefix: nil, allow_nil: nil, private: nil)
|
|
161
|
+
::ActiveSupport::Delegation.generate(
|
|
162
|
+
self,
|
|
163
|
+
methods,
|
|
164
|
+
location: caller_locations(1, 1).first,
|
|
165
|
+
to: to,
|
|
166
|
+
prefix: prefix,
|
|
167
|
+
allow_nil: allow_nil,
|
|
168
|
+
private: private,
|
|
169
|
+
)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# When building decorators, a common pattern may emerge:
|
|
173
|
+
#
|
|
174
|
+
# class Partition
|
|
175
|
+
# def initialize(event)
|
|
176
|
+
# @event = event
|
|
177
|
+
# end
|
|
178
|
+
#
|
|
179
|
+
# def person
|
|
180
|
+
# detail.person || creator
|
|
181
|
+
# end
|
|
182
|
+
#
|
|
183
|
+
# private
|
|
184
|
+
# def respond_to_missing?(name, include_private = false)
|
|
185
|
+
# @event.respond_to?(name, include_private)
|
|
186
|
+
# end
|
|
187
|
+
#
|
|
188
|
+
# def method_missing(method, *args, &block)
|
|
189
|
+
# @event.send(method, *args, &block)
|
|
190
|
+
# end
|
|
191
|
+
# end
|
|
192
|
+
#
|
|
193
|
+
# With <tt>Module#delegate_missing_to</tt>, the above is condensed to:
|
|
194
|
+
#
|
|
195
|
+
# class Partition
|
|
196
|
+
# delegate_missing_to :@event
|
|
197
|
+
#
|
|
198
|
+
# def initialize(event)
|
|
199
|
+
# @event = event
|
|
200
|
+
# end
|
|
201
|
+
#
|
|
202
|
+
# def person
|
|
203
|
+
# detail.person || creator
|
|
204
|
+
# end
|
|
205
|
+
# end
|
|
206
|
+
#
|
|
207
|
+
# The target can be anything callable within the object, e.g. instance
|
|
208
|
+
# variables, methods, constants, etc.
|
|
209
|
+
#
|
|
210
|
+
# The delegated method must be public on the target, otherwise it will
|
|
211
|
+
# raise +ActiveSupport::DelegationError+. If you wish to instead return +nil+,
|
|
212
|
+
# use the <tt>:allow_nil</tt> option.
|
|
213
|
+
#
|
|
214
|
+
# The <tt>marshal_dump</tt> and <tt>_dump</tt> methods are exempt from
|
|
215
|
+
# delegation due to possible interference when calling
|
|
216
|
+
# <tt>Marshal.dump(object)</tt>, should the delegation target method
|
|
217
|
+
# of <tt>object</tt> add or remove instance variables.
|
|
218
|
+
def delegate_missing_to(target, allow_nil: nil)
|
|
219
|
+
::ActiveSupport::Delegation.generate_method_missing(
|
|
220
|
+
self,
|
|
221
|
+
target,
|
|
222
|
+
allow_nil: allow_nil,
|
|
223
|
+
)
|
|
224
|
+
end
|
|
225
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Module
|
|
4
|
+
# deprecate :foo, deprecator: MyLib.deprecator
|
|
5
|
+
# deprecate :foo, bar: "warning!", deprecator: MyLib.deprecator
|
|
6
|
+
#
|
|
7
|
+
# A deprecator is typically an instance of ActiveSupport::Deprecation, but you can also pass any object that responds
|
|
8
|
+
# to <tt>deprecation_warning(deprecated_method_name, message, caller_backtrace)</tt> where you can implement your
|
|
9
|
+
# custom warning behavior.
|
|
10
|
+
#
|
|
11
|
+
# class MyLib::Deprecator
|
|
12
|
+
# def deprecation_warning(deprecated_method_name, message, caller_backtrace = nil)
|
|
13
|
+
# message = "#{deprecated_method_name} is deprecated and will be removed from MyLibrary | #{message}"
|
|
14
|
+
# Kernel.warn message
|
|
15
|
+
# end
|
|
16
|
+
# end
|
|
17
|
+
def deprecate(*method_names, deprecator:, **options)
|
|
18
|
+
if deprecator.is_a?(ActiveSupport::Deprecation)
|
|
19
|
+
deprecator.deprecate_methods(self, *method_names, **options)
|
|
20
|
+
elsif deprecator
|
|
21
|
+
# we just need any instance to call deprecate_methods, but the deprecation will be emitted by deprecator
|
|
22
|
+
ActiveSupport.deprecator.deprecate_methods(self, *method_names, **options, deprecator: deprecator)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/inflector"
|
|
4
|
+
|
|
5
|
+
class Module
|
|
6
|
+
# Returns the name of the module containing this one.
|
|
7
|
+
#
|
|
8
|
+
# M::N.module_parent_name # => "M"
|
|
9
|
+
def module_parent_name
|
|
10
|
+
if defined?(@parent_name)
|
|
11
|
+
@parent_name
|
|
12
|
+
else
|
|
13
|
+
name = self.name
|
|
14
|
+
return if name.nil?
|
|
15
|
+
|
|
16
|
+
parent_name = name =~ /::[^:]+\z/ ? -$` : nil
|
|
17
|
+
@parent_name = parent_name unless frozen?
|
|
18
|
+
parent_name
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Returns the module which contains this one according to its name.
|
|
23
|
+
#
|
|
24
|
+
# module M
|
|
25
|
+
# module N
|
|
26
|
+
# end
|
|
27
|
+
# end
|
|
28
|
+
# X = M::N
|
|
29
|
+
#
|
|
30
|
+
# M::N.module_parent # => M
|
|
31
|
+
# X.module_parent # => M
|
|
32
|
+
#
|
|
33
|
+
# The parent of top-level and anonymous modules is Object.
|
|
34
|
+
#
|
|
35
|
+
# M.module_parent # => Object
|
|
36
|
+
# Module.new.module_parent # => Object
|
|
37
|
+
def module_parent
|
|
38
|
+
module_parent_name ? ActiveSupport::Inflector.constantize(module_parent_name) : Object
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Returns all the parents of this module according to its name, ordered from
|
|
42
|
+
# nested outwards. The receiver is not contained within the result.
|
|
43
|
+
#
|
|
44
|
+
# module M
|
|
45
|
+
# module N
|
|
46
|
+
# end
|
|
47
|
+
# end
|
|
48
|
+
# X = M::N
|
|
49
|
+
#
|
|
50
|
+
# M.module_parents # => [Object]
|
|
51
|
+
# M::N.module_parents # => [M, Object]
|
|
52
|
+
# X.module_parents # => [M, Object]
|
|
53
|
+
def module_parents
|
|
54
|
+
parents = []
|
|
55
|
+
if module_parent_name
|
|
56
|
+
parts = module_parent_name.split("::")
|
|
57
|
+
until parts.empty?
|
|
58
|
+
parents << ActiveSupport::Inflector.constantize(parts * "::")
|
|
59
|
+
parts.pop
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
parents << Object unless parents.include? Object
|
|
63
|
+
parents
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -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
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_support/core_ext/module/redefine_method"
|
|
4
|
+
|
|
5
|
+
class Module
|
|
6
|
+
# Removes the named method, if it exists.
|
|
7
|
+
def remove_possible_method(method)
|
|
8
|
+
if method_defined?(method) || private_method_defined?(method)
|
|
9
|
+
undef_method(method)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Removes the named singleton method, if it exists.
|
|
14
|
+
def remove_possible_singleton_method(method)
|
|
15
|
+
singleton_class.remove_possible_method(method)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "module/aliasing"
|
|
4
|
+
require_relative "module/introspection"
|
|
5
|
+
require_relative "module/anonymous"
|
|
6
|
+
require_relative "module/attribute_accessors"
|
|
7
|
+
require_relative "module/attribute_accessors_per_thread"
|
|
8
|
+
require_relative "module/attr_internal"
|
|
9
|
+
require_relative "module/concerning"
|
|
10
|
+
require_relative "module/delegation"
|
|
11
|
+
require_relative "module/deprecation"
|
|
12
|
+
require_relative "module/redefine_method"
|
|
13
|
+
require_relative "module/remove_method"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class NameError
|
|
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"
|
|
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
|
+
return unless message.start_with?("uninitialized constant ")
|
|
18
|
+
|
|
19
|
+
receiver = begin
|
|
20
|
+
self.receiver
|
|
21
|
+
rescue ArgumentError
|
|
22
|
+
nil
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if receiver == Object
|
|
26
|
+
name.to_s
|
|
27
|
+
elsif receiver
|
|
28
|
+
"#{real_mod_name(receiver)}::#{self.name}"
|
|
29
|
+
else
|
|
30
|
+
if match = message.match(/((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/)
|
|
31
|
+
match[1]
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Was this exception raised because the given name was missing?
|
|
37
|
+
#
|
|
38
|
+
# begin
|
|
39
|
+
# HelloWorld
|
|
40
|
+
# rescue NameError => e
|
|
41
|
+
# e.missing_name?("HelloWorld")
|
|
42
|
+
# end
|
|
43
|
+
# # => true
|
|
44
|
+
def missing_name?(name)
|
|
45
|
+
if name.is_a? Symbol
|
|
46
|
+
self.name == name
|
|
47
|
+
else
|
|
48
|
+
missing_name == name.to_s
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
UNBOUND_METHOD_MODULE_NAME = Module.instance_method(:name)
|
|
54
|
+
private_constant :UNBOUND_METHOD_MODULE_NAME
|
|
55
|
+
|
|
56
|
+
def real_mod_name(mod)
|
|
57
|
+
UNBOUND_METHOD_MODULE_NAME.bind_call(mod)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -1,44 +1,75 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Numeric
|
|
4
|
+
KILOBYTE = 1024
|
|
5
|
+
MEGABYTE = KILOBYTE * 1024
|
|
6
|
+
GIGABYTE = MEGABYTE * 1024
|
|
7
|
+
TERABYTE = GIGABYTE * 1024
|
|
8
|
+
PETABYTE = TERABYTE * 1024
|
|
9
|
+
EXABYTE = PETABYTE * 1024
|
|
10
|
+
ZETTABYTE = EXABYTE * 1024
|
|
11
|
+
|
|
12
|
+
# Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
|
|
13
|
+
#
|
|
14
|
+
# 2.bytes # => 2
|
|
15
|
+
def bytes
|
|
16
|
+
self
|
|
17
|
+
end
|
|
18
|
+
alias :byte :bytes
|
|
19
|
+
|
|
20
|
+
# Returns the number of bytes equivalent to the kilobytes provided.
|
|
21
|
+
#
|
|
22
|
+
# 2.kilobytes # => 2048
|
|
23
|
+
def kilobytes
|
|
24
|
+
self * KILOBYTE
|
|
25
|
+
end
|
|
26
|
+
alias :kilobyte :kilobytes
|
|
27
|
+
|
|
28
|
+
# Returns the number of bytes equivalent to the megabytes provided.
|
|
29
|
+
#
|
|
30
|
+
# 2.megabytes # => 2_097_152
|
|
31
|
+
def megabytes
|
|
32
|
+
self * MEGABYTE
|
|
33
|
+
end
|
|
34
|
+
alias :megabyte :megabytes
|
|
35
|
+
|
|
36
|
+
# Returns the number of bytes equivalent to the gigabytes provided.
|
|
37
|
+
#
|
|
38
|
+
# 2.gigabytes # => 2_147_483_648
|
|
39
|
+
def gigabytes
|
|
40
|
+
self * GIGABYTE
|
|
41
|
+
end
|
|
42
|
+
alias :gigabyte :gigabytes
|
|
43
|
+
|
|
44
|
+
# Returns the number of bytes equivalent to the terabytes provided.
|
|
45
|
+
#
|
|
46
|
+
# 2.terabytes # => 2_199_023_255_552
|
|
47
|
+
def terabytes
|
|
48
|
+
self * TERABYTE
|
|
49
|
+
end
|
|
50
|
+
alias :terabyte :terabytes
|
|
51
|
+
|
|
52
|
+
# Returns the number of bytes equivalent to the petabytes provided.
|
|
53
|
+
#
|
|
54
|
+
# 2.petabytes # => 2_251_799_813_685_248
|
|
55
|
+
def petabytes
|
|
56
|
+
self * PETABYTE
|
|
57
|
+
end
|
|
58
|
+
alias :petabyte :petabytes
|
|
59
|
+
|
|
60
|
+
# Returns the number of bytes equivalent to the exabytes provided.
|
|
61
|
+
#
|
|
62
|
+
# 2.exabytes # => 2_305_843_009_213_693_952
|
|
63
|
+
def exabytes
|
|
64
|
+
self * EXABYTE
|
|
65
|
+
end
|
|
66
|
+
alias :exabyte :exabytes
|
|
67
|
+
|
|
68
|
+
# Returns the number of bytes equivalent to the zettabytes provided.
|
|
69
|
+
#
|
|
70
|
+
# 2.zettabytes # => 2_361_183_241_434_822_606_848
|
|
71
|
+
def zettabytes
|
|
72
|
+
self * ZETTABYTE
|
|
43
73
|
end
|
|
74
|
+
alias :zettabyte :zettabytes
|
|
44
75
|
end
|