activesupport 3.1.0 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/CHANGELOG.md +798 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +13 -7
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +38 -34
- data/lib/active_support/benchmarkable.rb +17 -28
- data/lib/active_support/cache/file_store.rb +85 -70
- data/lib/active_support/cache/mem_cache_store.rb +75 -66
- data/lib/active_support/cache/memory_store.rb +31 -23
- data/lib/active_support/cache/null_store.rb +41 -0
- data/lib/active_support/cache/strategy/local_cache.rb +73 -70
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
- data/lib/active_support/cache.rb +360 -294
- data/lib/active_support/callbacks.rb +563 -393
- data/lib/active_support/concern.rb +42 -34
- data/lib/active_support/concurrency/latch.rb +19 -0
- data/lib/active_support/concurrency/share_lock.rb +186 -0
- data/lib/active_support/configurable.rb +70 -12
- data/lib/active_support/core_ext/array/access.rb +53 -9
- data/lib/active_support/core_ext/array/conversions.rb +109 -62
- data/lib/active_support/core_ext/array/extract_options.rb +2 -2
- data/lib/active_support/core_ext/array/grouping.rb +39 -32
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
- data/lib/active_support/core_ext/array/wrap.rb +16 -18
- data/lib/active_support/core_ext/array.rb +2 -2
- data/lib/active_support/core_ext/benchmark.rb +7 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -36
- data/lib/active_support/core_ext/class/attribute.rb +47 -34
- data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -79
- data/lib/active_support/core_ext/class/subclasses.rb +12 -7
- data/lib/active_support/core_ext/class.rb +0 -3
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +57 -167
- data/lib/active_support/core_ext/date/conversions.rb +31 -42
- data/lib/active_support/core_ext/date/zones.rb +2 -10
- data/lib/active_support/core_ext/date.rb +5 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -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 +1 -0
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +132 -65
- data/lib/active_support/core_ext/date_time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/date_time/conversions.rb +36 -34
- data/lib/active_support/core_ext/date_time.rb +5 -0
- data/lib/active_support/core_ext/digest/uuid.rb +51 -0
- data/lib/active_support/core_ext/enumerable.rb +81 -74
- data/lib/active_support/core_ext/file/atomic.rb +53 -26
- data/lib/active_support/core_ext/file.rb +0 -1
- data/lib/active_support/core_ext/hash/compact.rb +20 -0
- data/lib/active_support/core_ext/hash/conversions.rb +175 -70
- data/lib/active_support/core_ext/hash/deep_merge.rb +30 -8
- data/lib/active_support/core_ext/hash/except.rb +11 -12
- data/lib/active_support/core_ext/hash/indifferent_access.rb +7 -8
- data/lib/active_support/core_ext/hash/keys.rb +147 -24
- data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
- data/lib/active_support/core_ext/hash/slice.rb +22 -14
- data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
- data/lib/active_support/core_ext/hash.rb +2 -2
- data/lib/active_support/core_ext/integer/inflections.rb +13 -1
- data/lib/active_support/core_ext/integer/multiple.rb +4 -0
- data/lib/active_support/core_ext/integer/time.rb +12 -22
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -2
- data/lib/active_support/core_ext/kernel/concern.rb +12 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +2 -15
- data/lib/active_support/core_ext/kernel/reporting.rb +12 -62
- data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
- data/lib/active_support/core_ext/kernel.rb +2 -3
- data/lib/active_support/core_ext/load_error.rb +14 -7
- data/lib/active_support/core_ext/marshal.rb +22 -0
- data/lib/active_support/core_ext/module/aliasing.rb +16 -12
- data/lib/active_support/core_ext/module/anonymous.rb +12 -8
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +165 -13
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +135 -0
- data/lib/active_support/core_ext/module/delegation.rb +141 -68
- data/lib/active_support/core_ext/module/deprecation.rb +17 -3
- data/lib/active_support/core_ext/module/introspection.rb +9 -31
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
- data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
- data/lib/active_support/core_ext/module/reachable.rb +1 -3
- data/lib/active_support/core_ext/module/remove_method.rb +24 -5
- data/lib/active_support/core_ext/module.rb +3 -3
- data/lib/active_support/core_ext/name_error.rb +15 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +145 -0
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +31 -36
- data/lib/active_support/core_ext/numeric.rb +2 -0
- data/lib/active_support/core_ext/object/acts_like.rb +4 -4
- data/lib/active_support/core_ext/object/blank.rb +52 -18
- data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
- data/lib/active_support/core_ext/object/duplicable.rb +12 -20
- data/lib/active_support/core_ext/object/inclusion.rb +13 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
- data/lib/active_support/core_ext/object/json.rb +205 -0
- data/lib/active_support/core_ext/object/to_param.rb +1 -55
- data/lib/active_support/core_ext/object/to_query.rb +66 -9
- data/lib/active_support/core_ext/object/try.rb +124 -33
- data/lib/active_support/core_ext/object/with_options.rb +37 -11
- data/lib/active_support/core_ext/object.rb +2 -1
- data/lib/active_support/core_ext/range/conversions.rb +17 -7
- data/lib/active_support/core_ext/range/each.rb +21 -0
- data/lib/active_support/core_ext/range/include_range.rb +20 -18
- data/lib/active_support/core_ext/range/overlaps.rb +1 -1
- data/lib/active_support/core_ext/range.rb +1 -2
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/access.rb +95 -90
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +41 -38
- data/lib/active_support/core_ext/string/exclude.rb +6 -1
- data/lib/active_support/core_ext/string/filters.rb +70 -17
- data/lib/active_support/core_ext/string/indent.rb +43 -0
- data/lib/active_support/core_ext/string/inflections.rb +139 -59
- data/lib/active_support/core_ext/string/inquiry.rb +2 -2
- data/lib/active_support/core_ext/string/multibyte.rb +46 -65
- data/lib/active_support/core_ext/string/output_safety.rb +153 -56
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/string/zones.rb +14 -0
- data/lib/active_support/core_ext/string.rb +2 -3
- data/lib/active_support/core_ext/struct.rb +3 -0
- data/lib/active_support/core_ext/time/calculations.rb +173 -173
- data/lib/active_support/core_ext/time/compatibility.rb +5 -0
- data/lib/active_support/core_ext/time/conversions.rb +33 -29
- data/lib/active_support/core_ext/time/marshal.rb +2 -56
- data/lib/active_support/core_ext/time/zones.rb +57 -32
- data/lib/active_support/core_ext/time.rb +5 -0
- data/lib/active_support/core_ext/uri.rb +13 -19
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/dependencies/autoload.rb +47 -20
- data/lib/active_support/dependencies/interlock.rb +51 -0
- data/lib/active_support/dependencies.rb +315 -265
- data/lib/active_support/deprecation/behaviors.rb +71 -30
- data/lib/active_support/deprecation/instance_delegator.rb +24 -0
- data/lib/active_support/deprecation/method_wrappers.rb +59 -18
- data/lib/active_support/deprecation/proxy_wrappers.rb +82 -14
- data/lib/active_support/deprecation/reporting.rb +61 -14
- data/lib/active_support/deprecation.rb +38 -13
- data/lib/active_support/descendants_tracker.rb +34 -19
- data/lib/active_support/duration/iso8601_parser.rb +122 -0
- data/lib/active_support/duration/iso8601_serializer.rb +51 -0
- data/lib/active_support/duration.rb +85 -14
- data/lib/active_support/evented_file_update_checker.rb +194 -0
- data/lib/active_support/execution_wrapper.rb +117 -0
- data/lib/active_support/executor.rb +6 -0
- data/lib/active_support/file_update_checker.rb +138 -17
- data/lib/active_support/gem_version.rb +15 -0
- data/lib/active_support/gzip.rb +11 -5
- data/lib/active_support/hash_with_indifferent_access.rb +199 -49
- data/lib/active_support/i18n.rb +6 -2
- data/lib/active_support/i18n_railtie.rb +40 -21
- data/lib/active_support/inflections.rb +22 -13
- data/lib/active_support/inflector/inflections.rb +175 -144
- data/lib/active_support/inflector/methods.rb +328 -91
- data/lib/active_support/inflector/transliterate.rb +51 -37
- data/lib/active_support/json/decoding.rb +31 -22
- data/lib/active_support/json/encoding.rb +88 -248
- data/lib/active_support/key_generator.rb +71 -0
- data/lib/active_support/lazy_load_hooks.rb +27 -25
- data/lib/active_support/locale/en.yml +102 -3
- data/lib/active_support/log_subscriber/test_helper.rb +24 -21
- data/lib/active_support/log_subscriber.rb +36 -49
- data/lib/active_support/logger.rb +106 -0
- data/lib/active_support/logger_silence.rb +28 -0
- data/lib/active_support/logger_thread_safe_level.rb +31 -0
- data/lib/active_support/message_encryptor.rb +72 -36
- data/lib/active_support/message_verifier.rb +96 -24
- data/lib/active_support/multibyte/chars.rb +88 -333
- data/lib/active_support/multibyte/unicode.rb +156 -136
- data/lib/active_support/multibyte.rb +5 -28
- data/lib/active_support/notifications/fanout.rb +115 -19
- data/lib/active_support/notifications/instrumenter.rb +52 -15
- data/lib/active_support/notifications.rb +168 -33
- data/lib/active_support/number_helper/number_converter.rb +182 -0
- data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -0
- data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +62 -0
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
- data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +92 -0
- data/lib/active_support/number_helper.rb +368 -0
- data/lib/active_support/option_merger.rb +1 -1
- data/lib/active_support/ordered_hash.rb +18 -183
- data/lib/active_support/ordered_options.rb +44 -24
- data/lib/active_support/per_thread_registry.rb +58 -0
- data/lib/active_support/proxy_object.rb +13 -0
- data/lib/active_support/rails.rb +27 -0
- data/lib/active_support/railtie.rb +25 -34
- data/lib/active_support/reloader.rb +129 -0
- data/lib/active_support/rescuable.rb +98 -48
- data/lib/active_support/security_utils.rb +27 -0
- data/lib/active_support/string_inquirer.rb +14 -9
- data/lib/active_support/subscriber.rb +120 -0
- data/lib/active_support/tagged_logging.rb +78 -0
- data/lib/active_support/test_case.rb +69 -17
- data/lib/active_support/testing/assertions.rb +43 -41
- data/lib/active_support/testing/autorun.rb +12 -0
- data/lib/active_support/testing/constant_lookup.rb +50 -0
- data/lib/active_support/testing/declarative.rb +7 -21
- data/lib/active_support/testing/deprecation.rb +14 -33
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +53 -95
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/setup_and_teardown.rb +21 -82
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/tagged_logging.rb +25 -0
- data/lib/active_support/testing/time_helpers.rb +134 -0
- data/lib/active_support/time.rb +6 -23
- data/lib/active_support/time_with_zone.rb +239 -92
- data/lib/active_support/values/time_zone.rb +236 -160
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +5 -7
- data/lib/active_support/xml_mini/jdom.rb +19 -13
- data/lib/active_support/xml_mini/libxml.rb +3 -4
- data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
- data/lib/active_support/xml_mini/nokogiri.rb +3 -4
- data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
- data/lib/active_support/xml_mini/rexml.rb +8 -10
- data/lib/active_support/xml_mini.rb +66 -34
- data/lib/active_support.rb +40 -23
- metadata +185 -134
- data/CHANGELOG +0 -1534
- data/lib/active_support/base64.rb +0 -42
- data/lib/active_support/basic_object.rb +0 -21
- data/lib/active_support/buffered_logger.rb +0 -137
- data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
- data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
- data/lib/active_support/core_ext/array/random_access.rb +0 -30
- data/lib/active_support/core_ext/array/uniq_by.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -44
- data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -178
- data/lib/active_support/core_ext/date/freeze.rb +0 -31
- data/lib/active_support/core_ext/date_time/zones.rb +0 -21
- data/lib/active_support/core_ext/exception.rb +0 -3
- data/lib/active_support/core_ext/file/path.rb +0 -5
- data/lib/active_support/core_ext/float/rounding.rb +0 -19
- data/lib/active_support/core_ext/float.rb +0 -1
- data/lib/active_support/core_ext/hash/deep_dup.rb +0 -11
- data/lib/active_support/core_ext/hash/diff.rb +0 -13
- data/lib/active_support/core_ext/kernel/requires.rb +0 -28
- data/lib/active_support/core_ext/logger.rb +0 -81
- data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
- data/lib/active_support/core_ext/module/method_names.rb +0 -14
- data/lib/active_support/core_ext/module/synchronization.rb +0 -43
- data/lib/active_support/core_ext/object/to_json.rb +0 -19
- data/lib/active_support/core_ext/proc.rb +0 -14
- data/lib/active_support/core_ext/process/daemon.rb +0 -23
- data/lib/active_support/core_ext/process.rb +0 -1
- data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
- data/lib/active_support/core_ext/range/cover.rb +0 -3
- data/lib/active_support/core_ext/rexml.rb +0 -46
- data/lib/active_support/core_ext/string/encoding.rb +0 -11
- data/lib/active_support/core_ext/string/interpolation.rb +0 -2
- data/lib/active_support/core_ext/string/xchar.rb +0 -18
- data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
- data/lib/active_support/file_watcher.rb +0 -36
- data/lib/active_support/json/variable.rb +0 -9
- data/lib/active_support/memoizable.rb +0 -105
- data/lib/active_support/multibyte/exceptions.rb +0 -8
- data/lib/active_support/multibyte/utils.rb +0 -60
- data/lib/active_support/ruby/shim.rb +0 -22
- data/lib/active_support/secure_random.rb +0 -6
- data/lib/active_support/testing/mochaing.rb +0 -7
- data/lib/active_support/testing/pending.rb +0 -52
- data/lib/active_support/testing/performance/jruby.rb +0 -115
- data/lib/active_support/testing/performance/rubinius.rb +0 -113
- data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
- data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
- data/lib/active_support/testing/performance/ruby.rb +0 -152
- data/lib/active_support/testing/performance.rb +0 -317
- data/lib/active_support/time/autoload.rb +0 -5
- data/lib/active_support/whiny_nil.rb +0 -60
@@ -1,26 +1,44 @@
|
|
1
|
-
require
|
1
|
+
require 'set'
|
2
2
|
|
3
3
|
class Module
|
4
|
-
#
|
5
|
-
#
|
6
|
-
|
7
|
-
|
4
|
+
# Error generated by +delegate+ when a method is called on +nil+ and +allow_nil+
|
5
|
+
# option is not used.
|
6
|
+
class DelegationError < NoMethodError; end
|
7
|
+
|
8
|
+
DELEGATION_RESERVED_METHOD_NAMES = Set.new(
|
9
|
+
%w(_ arg args alias and BEGIN begin block break case class def defined? do
|
10
|
+
else elsif END end ensure false for if in module next nil not or redo
|
11
|
+
rescue retry return self super then true undef unless until when while
|
12
|
+
yield)
|
13
|
+
).freeze
|
14
|
+
|
15
|
+
# Provides a +delegate+ class method to easily expose contained objects'
|
16
|
+
# public methods as your own.
|
17
|
+
#
|
18
|
+
# ==== Options
|
19
|
+
# * <tt>:to</tt> - Specifies the target object
|
20
|
+
# * <tt>:prefix</tt> - Prefixes the new method with the target name or a custom prefix
|
21
|
+
# * <tt>:allow_nil</tt> - if set to true, prevents a +NoMethodError+ from being raised
|
22
|
+
#
|
23
|
+
# The macro receives one or more method names (specified as symbols or
|
24
|
+
# strings) and the name of the target object via the <tt>:to</tt> option
|
25
|
+
# (also a symbol or string).
|
8
26
|
#
|
9
27
|
# Delegation is particularly useful with Active Record associations:
|
10
28
|
#
|
11
29
|
# class Greeter < ActiveRecord::Base
|
12
30
|
# def hello
|
13
|
-
#
|
31
|
+
# 'hello'
|
14
32
|
# end
|
15
33
|
#
|
16
34
|
# def goodbye
|
17
|
-
#
|
35
|
+
# 'goodbye'
|
18
36
|
# end
|
19
37
|
# end
|
20
38
|
#
|
21
39
|
# class Foo < ActiveRecord::Base
|
22
40
|
# belongs_to :greeter
|
23
|
-
# delegate :hello, :
|
41
|
+
# delegate :hello, to: :greeter
|
24
42
|
# end
|
25
43
|
#
|
26
44
|
# Foo.new.hello # => "hello"
|
@@ -30,7 +48,7 @@ class Module
|
|
30
48
|
#
|
31
49
|
# class Foo < ActiveRecord::Base
|
32
50
|
# belongs_to :greeter
|
33
|
-
# delegate :hello, :goodbye, :
|
51
|
+
# delegate :hello, :goodbye, to: :greeter
|
34
52
|
# end
|
35
53
|
#
|
36
54
|
# Foo.new.goodbye # => "goodbye"
|
@@ -45,15 +63,27 @@ class Module
|
|
45
63
|
# def initialize
|
46
64
|
# @instance_array = [8,9,10,11]
|
47
65
|
# end
|
48
|
-
# delegate :sum, :
|
49
|
-
# delegate :min, :
|
50
|
-
# delegate :max, :
|
66
|
+
# delegate :sum, to: :CONSTANT_ARRAY
|
67
|
+
# delegate :min, to: :@@class_array
|
68
|
+
# delegate :max, to: :@instance_array
|
51
69
|
# end
|
52
70
|
#
|
53
71
|
# Foo.new.sum # => 6
|
54
72
|
# Foo.new.min # => 4
|
55
73
|
# Foo.new.max # => 11
|
56
74
|
#
|
75
|
+
# It's also possible to delegate a method to the class by using +:class+:
|
76
|
+
#
|
77
|
+
# class Foo
|
78
|
+
# def self.hello
|
79
|
+
# "world"
|
80
|
+
# end
|
81
|
+
#
|
82
|
+
# delegate :hello, to: :class
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# Foo.new.hello # => "world"
|
86
|
+
#
|
57
87
|
# Delegates can optionally be prefixed using the <tt>:prefix</tt> option. If the value
|
58
88
|
# is <tt>true</tt>, the delegate methods are prefixed with the name of the object being
|
59
89
|
# delegated to.
|
@@ -61,10 +91,10 @@ class Module
|
|
61
91
|
# Person = Struct.new(:name, :address)
|
62
92
|
#
|
63
93
|
# class Invoice < Struct.new(:client)
|
64
|
-
# delegate :name, :address, :
|
94
|
+
# delegate :name, :address, to: :client, prefix: true
|
65
95
|
# end
|
66
96
|
#
|
67
|
-
# john_doe = Person.new(
|
97
|
+
# john_doe = Person.new('John Doe', 'Vimmersvej 13')
|
68
98
|
# invoice = Invoice.new(john_doe)
|
69
99
|
# invoice.client_name # => "John Doe"
|
70
100
|
# invoice.client_address # => "Vimmersvej 13"
|
@@ -72,71 +102,114 @@ class Module
|
|
72
102
|
# It is also possible to supply a custom prefix.
|
73
103
|
#
|
74
104
|
# class Invoice < Struct.new(:client)
|
75
|
-
# delegate :name, :address, :
|
105
|
+
# delegate :name, :address, to: :client, prefix: :customer
|
76
106
|
# end
|
77
107
|
#
|
78
108
|
# invoice = Invoice.new(john_doe)
|
79
|
-
# invoice.customer_name # =>
|
80
|
-
# invoice.customer_address # =>
|
81
|
-
#
|
82
|
-
# If the
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
#
|
90
|
-
#
|
91
|
-
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#
|
97
|
-
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
109
|
+
# invoice.customer_name # => 'John Doe'
|
110
|
+
# invoice.customer_address # => 'Vimmersvej 13'
|
111
|
+
#
|
112
|
+
# If the target is +nil+ and does not respond to the delegated method a
|
113
|
+
# +NoMethodError+ is raised, as with any other value. Sometimes, however, it
|
114
|
+
# makes sense to be robust to that situation and that is the purpose of the
|
115
|
+
# <tt>:allow_nil</tt> option: If the target is not +nil+, or it is and
|
116
|
+
# responds to the method, everything works as usual. But if it is +nil+ and
|
117
|
+
# does not respond to the delegated method, +nil+ is returned.
|
118
|
+
#
|
119
|
+
# class User < ActiveRecord::Base
|
120
|
+
# has_one :profile
|
121
|
+
# delegate :age, to: :profile
|
122
|
+
# end
|
123
|
+
#
|
124
|
+
# User.new.age # raises NoMethodError: undefined method `age'
|
125
|
+
#
|
126
|
+
# But if not having a profile yet is fine and should not be an error
|
127
|
+
# condition:
|
128
|
+
#
|
129
|
+
# class User < ActiveRecord::Base
|
130
|
+
# has_one :profile
|
131
|
+
# delegate :age, to: :profile, allow_nil: true
|
132
|
+
# end
|
133
|
+
#
|
134
|
+
# User.new.age # nil
|
135
|
+
#
|
136
|
+
# Note that if the target is not +nil+ then the call is attempted regardless of the
|
137
|
+
# <tt>:allow_nil</tt> option, and thus an exception is still raised if said object
|
138
|
+
# does not respond to the method:
|
139
|
+
#
|
140
|
+
# class Foo
|
141
|
+
# def initialize(bar)
|
142
|
+
# @bar = bar
|
143
|
+
# end
|
144
|
+
#
|
145
|
+
# delegate :name, to: :@bar, allow_nil: true
|
146
|
+
# end
|
147
|
+
#
|
148
|
+
# Foo.new("Bar").name # raises NoMethodError: undefined method `name'
|
149
|
+
#
|
150
|
+
# The target method must be public, otherwise it will raise +NoMethodError+.
|
151
|
+
#
|
152
|
+
def delegate(*methods, to: nil, prefix: nil, allow_nil: nil)
|
153
|
+
unless 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).'
|
110
155
|
end
|
111
156
|
|
112
|
-
if
|
113
|
-
raise ArgumentError,
|
157
|
+
if prefix == true && to =~ /^[^a-z_]/
|
158
|
+
raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
|
114
159
|
end
|
115
160
|
|
116
|
-
|
161
|
+
method_prefix = \
|
162
|
+
if prefix
|
163
|
+
"#{prefix == true ? to : prefix}_"
|
164
|
+
else
|
165
|
+
''
|
166
|
+
end
|
117
167
|
|
118
|
-
|
119
|
-
line =
|
168
|
+
location = caller_locations(1, 1).first
|
169
|
+
file, line = location.path, location.lineno
|
170
|
+
|
171
|
+
to = to.to_s
|
172
|
+
to = "self.#{to}" if DELEGATION_RESERVED_METHOD_NAMES.include?(to)
|
120
173
|
|
121
174
|
methods.each do |method|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
175
|
+
# Attribute writer methods only accept one argument. Makes sure []=
|
176
|
+
# methods still accept two arguments.
|
177
|
+
definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block'
|
178
|
+
|
179
|
+
# The following generated method calls the target exactly once, storing
|
180
|
+
# the returned value in a dummy variable.
|
181
|
+
#
|
182
|
+
# Reason is twofold: On one hand doing less calls is in general better.
|
183
|
+
# On the other hand it could be that the target has side-effects,
|
184
|
+
# whereas conceptually, from the user point of view, the delegator should
|
185
|
+
# be doing one call.
|
186
|
+
if allow_nil
|
187
|
+
method_def = [
|
188
|
+
"def #{method_prefix}#{method}(#{definition})",
|
189
|
+
"_ = #{to}",
|
190
|
+
"if !_.nil? || nil.respond_to?(:#{method})",
|
191
|
+
" _.#{method}(#{definition})",
|
192
|
+
"end",
|
193
|
+
"end"
|
194
|
+
].join ';'
|
195
|
+
else
|
196
|
+
exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
|
197
|
+
|
198
|
+
method_def = [
|
199
|
+
"def #{method_prefix}#{method}(#{definition})",
|
200
|
+
" _ = #{to}",
|
201
|
+
" _.#{method}(#{definition})",
|
202
|
+
"rescue NoMethodError => e",
|
203
|
+
" if _.nil? && e.name == :#{method}",
|
204
|
+
" #{exception}",
|
205
|
+
" else",
|
206
|
+
" raise",
|
207
|
+
" end",
|
208
|
+
"end"
|
209
|
+
].join ';'
|
210
|
+
end
|
128
211
|
|
129
|
-
module_eval(
|
130
|
-
def #{prefix}#{method}(*args, &block) # def customer_name(*args, &block)
|
131
|
-
#{to}.__send__(#{method.inspect}, *args, &block) # client.__send__(:name, *args, &block)
|
132
|
-
rescue NoMethodError # rescue NoMethodError
|
133
|
-
if #{to}.nil? # if client.nil?
|
134
|
-
#{on_nil} # return # depends on :allow_nil
|
135
|
-
else # else
|
136
|
-
raise # raise
|
137
|
-
end # end
|
138
|
-
end # end
|
139
|
-
EOS
|
212
|
+
module_eval(method_def, file, line)
|
140
213
|
end
|
141
214
|
end
|
142
215
|
end
|
@@ -1,8 +1,22 @@
|
|
1
1
|
class Module
|
2
|
-
# Declare that a method has been deprecated.
|
3
2
|
# deprecate :foo
|
4
|
-
# deprecate :
|
5
|
-
# deprecate :foo, :bar, :
|
3
|
+
# deprecate bar: 'message'
|
4
|
+
# deprecate :foo, :bar, baz: 'warning!', qux: 'gone!'
|
5
|
+
#
|
6
|
+
# You can also use custom deprecator instance:
|
7
|
+
#
|
8
|
+
# deprecate :foo, deprecator: MyLib::Deprecator.new
|
9
|
+
# deprecate :foo, bar: "warning!", deprecator: MyLib::Deprecator.new
|
10
|
+
#
|
11
|
+
# \Custom deprecators must respond to <tt>deprecation_warning(deprecated_method_name, message, caller_backtrace)</tt>
|
12
|
+
# method where you can implement your custom warning behavior.
|
13
|
+
#
|
14
|
+
# class MyLib::Deprecator
|
15
|
+
# def deprecation_warning(deprecated_method_name, message, caller_backtrace = nil)
|
16
|
+
# message = "#{deprecated_method_name} is deprecated and will be removed from MyLibrary | #{message}"
|
17
|
+
# Kernel.warn message
|
18
|
+
# end
|
19
|
+
# end
|
6
20
|
def deprecate(*method_names)
|
7
21
|
ActiveSupport::Deprecation.deprecate_methods(self, *method_names)
|
8
22
|
end
|
@@ -5,10 +5,11 @@ class Module
|
|
5
5
|
#
|
6
6
|
# M::N.parent_name # => "M"
|
7
7
|
def parent_name
|
8
|
-
|
8
|
+
if defined? @parent_name
|
9
|
+
@parent_name
|
10
|
+
else
|
9
11
|
@parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
|
10
12
|
end
|
11
|
-
@parent_name
|
12
13
|
end
|
13
14
|
|
14
15
|
# Returns the module which contains this one according to its name.
|
@@ -26,7 +27,6 @@ class Module
|
|
26
27
|
#
|
27
28
|
# M.parent # => Object
|
28
29
|
# Module.new.parent # => Object
|
29
|
-
#
|
30
30
|
def parent
|
31
31
|
parent_name ? ActiveSupport::Inflector.constantize(parent_name) : Object
|
32
32
|
end
|
@@ -43,7 +43,6 @@ class Module
|
|
43
43
|
# M.parents # => [Object]
|
44
44
|
# M::N.parents # => [M, Object]
|
45
45
|
# X.parents # => [M, Object]
|
46
|
-
#
|
47
46
|
def parents
|
48
47
|
parents = []
|
49
48
|
if parent_name
|
@@ -57,32 +56,11 @@ class Module
|
|
57
56
|
parents
|
58
57
|
end
|
59
58
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
inherited = {}
|
67
|
-
|
68
|
-
ancestors.each do |anc|
|
69
|
-
next if anc == self
|
70
|
-
anc.constants.each { |const| inherited[const] = anc.const_get(const) }
|
71
|
-
end
|
72
|
-
|
73
|
-
constants.select do |const|
|
74
|
-
!inherited.key?(const) || inherited[const].object_id != const_get(const).object_id
|
75
|
-
end
|
76
|
-
end
|
77
|
-
else
|
78
|
-
def local_constants #:nodoc:
|
79
|
-
constants(false)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
# Returns the names of the constants defined locally rather than the
|
84
|
-
# constants themselves. See <tt>local_constants</tt>.
|
85
|
-
def local_constant_names
|
86
|
-
local_constants.map { |c| c.to_s }
|
59
|
+
def local_constants #:nodoc:
|
60
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
61
|
+
Module#local_constants is deprecated and will be removed in Rails 5.1.
|
62
|
+
Use Module#constants(false) instead.
|
63
|
+
MSG
|
64
|
+
constants(false)
|
87
65
|
end
|
88
66
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Allows code reuse in the methods below without polluting Module.
|
5
|
+
#++
|
6
|
+
|
7
|
+
module ActiveSupport
|
8
|
+
module QualifiedConstUtils
|
9
|
+
def self.raise_if_absolute(path)
|
10
|
+
raise NameError.new("wrong constant name #$&") if path =~ /\A::[^:]+/
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.names(path)
|
14
|
+
path.split('::')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Extends the API for constants to be able to deal with qualified names. Arguments
|
21
|
+
# are assumed to be relative to the receiver.
|
22
|
+
#
|
23
|
+
#--
|
24
|
+
# Qualified names are required to be relative because we are extending existing
|
25
|
+
# methods that expect constant names, ie, relative paths of length 1. For example,
|
26
|
+
# Object.const_get('::String') raises NameError and so does qualified_const_get.
|
27
|
+
#++
|
28
|
+
class Module
|
29
|
+
def qualified_const_defined?(path, search_parents=true)
|
30
|
+
ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
|
31
|
+
Module#qualified_const_defined? is deprecated in favour of the builtin
|
32
|
+
Module#const_defined? and will be removed in Rails 5.1.
|
33
|
+
MESSAGE
|
34
|
+
|
35
|
+
ActiveSupport::QualifiedConstUtils.raise_if_absolute(path)
|
36
|
+
|
37
|
+
ActiveSupport::QualifiedConstUtils.names(path).inject(self) do |mod, name|
|
38
|
+
return unless mod.const_defined?(name, search_parents)
|
39
|
+
mod.const_get(name)
|
40
|
+
end
|
41
|
+
return true
|
42
|
+
end
|
43
|
+
|
44
|
+
def qualified_const_get(path)
|
45
|
+
ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
|
46
|
+
Module#qualified_const_get is deprecated in favour of the builtin
|
47
|
+
Module#const_get and will be removed in Rails 5.1.
|
48
|
+
MESSAGE
|
49
|
+
|
50
|
+
ActiveSupport::QualifiedConstUtils.raise_if_absolute(path)
|
51
|
+
|
52
|
+
ActiveSupport::QualifiedConstUtils.names(path).inject(self) do |mod, name|
|
53
|
+
mod.const_get(name)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def qualified_const_set(path, value)
|
58
|
+
ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
|
59
|
+
Module#qualified_const_set is deprecated in favour of the builtin
|
60
|
+
Module#const_set and will be removed in Rails 5.1.
|
61
|
+
MESSAGE
|
62
|
+
|
63
|
+
ActiveSupport::QualifiedConstUtils.raise_if_absolute(path)
|
64
|
+
|
65
|
+
const_name = path.demodulize
|
66
|
+
mod_name = path.deconstantize
|
67
|
+
mod = mod_name.empty? ? self : const_get(mod_name)
|
68
|
+
mod.const_set(const_name, value)
|
69
|
+
end
|
70
|
+
end
|
@@ -1,16 +1,35 @@
|
|
1
1
|
class Module
|
2
|
+
# Removes the named method, if it exists.
|
2
3
|
def remove_possible_method(method)
|
3
4
|
if method_defined?(method) || private_method_defined?(method)
|
4
|
-
|
5
|
+
undef_method(method)
|
5
6
|
end
|
6
|
-
rescue NameError
|
7
|
-
# If the requested method is defined on a superclass or included module,
|
8
|
-
# method_defined? returns true but remove_method throws a NameError.
|
9
|
-
# Ignore this.
|
10
7
|
end
|
11
8
|
|
9
|
+
# Removes the named singleton method, if it exists.
|
10
|
+
def remove_possible_singleton_method(method)
|
11
|
+
singleton_class.instance_eval do
|
12
|
+
remove_possible_method(method)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Replaces the existing method definition, if there is one, with the passed
|
17
|
+
# block as its body.
|
12
18
|
def redefine_method(method, &block)
|
19
|
+
visibility = method_visibility(method)
|
13
20
|
remove_possible_method(method)
|
14
21
|
define_method(method, &block)
|
22
|
+
send(visibility, method)
|
23
|
+
end
|
24
|
+
|
25
|
+
def method_visibility(method) # :nodoc:
|
26
|
+
case
|
27
|
+
when private_method_defined?(method)
|
28
|
+
:private
|
29
|
+
when protected_method_defined?(method)
|
30
|
+
:protected
|
31
|
+
else
|
32
|
+
:public
|
33
|
+
end
|
15
34
|
end
|
16
35
|
end
|
@@ -3,10 +3,10 @@ require 'active_support/core_ext/module/introspection'
|
|
3
3
|
require 'active_support/core_ext/module/anonymous'
|
4
4
|
require 'active_support/core_ext/module/reachable'
|
5
5
|
require 'active_support/core_ext/module/attribute_accessors'
|
6
|
+
require 'active_support/core_ext/module/attribute_accessors_per_thread'
|
6
7
|
require 'active_support/core_ext/module/attr_internal'
|
7
|
-
require 'active_support/core_ext/module/
|
8
|
+
require 'active_support/core_ext/module/concerning'
|
8
9
|
require 'active_support/core_ext/module/delegation'
|
9
|
-
require 'active_support/core_ext/module/synchronization'
|
10
10
|
require 'active_support/core_ext/module/deprecation'
|
11
11
|
require 'active_support/core_ext/module/remove_method'
|
12
|
-
require 'active_support/core_ext/module/
|
12
|
+
require 'active_support/core_ext/module/qualified_const'
|
@@ -1,5 +1,12 @@
|
|
1
1
|
class NameError
|
2
2
|
# Extract the name of the missing constant from the exception message.
|
3
|
+
#
|
4
|
+
# begin
|
5
|
+
# HelloWorld
|
6
|
+
# rescue NameError => e
|
7
|
+
# e.missing_name
|
8
|
+
# end
|
9
|
+
# # => "HelloWorld"
|
3
10
|
def missing_name
|
4
11
|
if /undefined local variable or method/ !~ message
|
5
12
|
$1 if /((::)?([A-Z]\w*)(::[A-Z]\w*)*)$/ =~ message
|
@@ -7,10 +14,16 @@ class NameError
|
|
7
14
|
end
|
8
15
|
|
9
16
|
# Was this exception raised because the given name was missing?
|
17
|
+
#
|
18
|
+
# begin
|
19
|
+
# HelloWorld
|
20
|
+
# rescue NameError => e
|
21
|
+
# e.missing_name?("HelloWorld")
|
22
|
+
# end
|
23
|
+
# # => true
|
10
24
|
def missing_name?(name)
|
11
25
|
if name.is_a? Symbol
|
12
|
-
|
13
|
-
last_name == name.to_s
|
26
|
+
self.name == name
|
14
27
|
else
|
15
28
|
missing_name == name.to_s
|
16
29
|
end
|
@@ -7,36 +7,56 @@ class Numeric
|
|
7
7
|
EXABYTE = PETABYTE * 1024
|
8
8
|
|
9
9
|
# Enables the use of byte calculations and declarations, like 45.bytes + 2.6.megabytes
|
10
|
+
#
|
11
|
+
# 2.bytes # => 2
|
10
12
|
def bytes
|
11
13
|
self
|
12
14
|
end
|
13
15
|
alias :byte :bytes
|
14
16
|
|
17
|
+
# Returns the number of bytes equivalent to the kilobytes provided.
|
18
|
+
#
|
19
|
+
# 2.kilobytes # => 2048
|
15
20
|
def kilobytes
|
16
21
|
self * KILOBYTE
|
17
22
|
end
|
18
23
|
alias :kilobyte :kilobytes
|
19
24
|
|
25
|
+
# Returns the number of bytes equivalent to the megabytes provided.
|
26
|
+
#
|
27
|
+
# 2.megabytes # => 2_097_152
|
20
28
|
def megabytes
|
21
29
|
self * MEGABYTE
|
22
30
|
end
|
23
31
|
alias :megabyte :megabytes
|
24
32
|
|
33
|
+
# Returns the number of bytes equivalent to the gigabytes provided.
|
34
|
+
#
|
35
|
+
# 2.gigabytes # => 2_147_483_648
|
25
36
|
def gigabytes
|
26
37
|
self * GIGABYTE
|
27
38
|
end
|
28
39
|
alias :gigabyte :gigabytes
|
29
40
|
|
41
|
+
# Returns the number of bytes equivalent to the terabytes provided.
|
42
|
+
#
|
43
|
+
# 2.terabytes # => 2_199_023_255_552
|
30
44
|
def terabytes
|
31
45
|
self * TERABYTE
|
32
46
|
end
|
33
47
|
alias :terabyte :terabytes
|
34
48
|
|
49
|
+
# Returns the number of bytes equivalent to the petabytes provided.
|
50
|
+
#
|
51
|
+
# 2.petabytes # => 2_251_799_813_685_248
|
35
52
|
def petabytes
|
36
53
|
self * PETABYTE
|
37
54
|
end
|
38
55
|
alias :petabyte :petabytes
|
39
56
|
|
57
|
+
# Returns the number of bytes equivalent to the exabytes provided.
|
58
|
+
#
|
59
|
+
# 2.exabytes # => 2_305_843_009_213_693_952
|
40
60
|
def exabytes
|
41
61
|
self * EXABYTE
|
42
62
|
end
|