activesupport 4.2.11.3 → 5.0.7.2
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 +678 -348
- data/MIT-LICENSE +2 -2
- data/README.rdoc +2 -3
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +1 -1
- data/lib/active_support/benchmarkable.rb +1 -1
- data/lib/active_support/cache/file_store.rb +36 -22
- data/lib/active_support/cache/mem_cache_store.rb +63 -54
- data/lib/active_support/cache/memory_store.rb +16 -21
- data/lib/active_support/cache/null_store.rb +1 -4
- data/lib/active_support/cache/strategy/local_cache.rb +31 -20
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +4 -4
- data/lib/active_support/cache.rb +71 -87
- data/lib/active_support/callbacks.rb +109 -113
- data/lib/active_support/concern.rb +1 -1
- data/lib/active_support/concurrency/latch.rb +11 -12
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +1 -0
- data/lib/active_support/core_ext/array/access.rb +27 -1
- data/lib/active_support/core_ext/array/conversions.rb +6 -4
- data/lib/active_support/core_ext/array/grouping.rb +9 -18
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/wrap.rb +5 -4
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
- data/lib/active_support/core_ext/class/attribute.rb +10 -9
- data/lib/active_support/core_ext/class/subclasses.rb +3 -2
- data/lib/active_support/core_ext/class.rb +0 -1
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +1 -1
- data/lib/active_support/core_ext/date/conversions.rb +7 -6
- data/lib/active_support/core_ext/date.rb +1 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +100 -27
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +3 -4
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +14 -8
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/date_time.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +75 -25
- data/lib/active_support/core_ext/file/atomic.rb +30 -25
- data/lib/active_support/core_ext/hash/conversions.rb +22 -2
- data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +9 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +25 -21
- data/lib/active_support/core_ext/hash/slice.rb +1 -1
- data/lib/active_support/core_ext/hash/transform_values.rb +11 -5
- data/lib/active_support/core_ext/integer/time.rb +2 -2
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
- data/lib/active_support/core_ext/kernel/reporting.rb +2 -84
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +5 -2
- data/lib/active_support/core_ext/marshal.rb +7 -9
- data/lib/active_support/core_ext/module/aliasing.rb +6 -1
- data/lib/active_support/core_ext/module/anonymous.rb +10 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +15 -15
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +4 -4
- data/lib/active_support/core_ext/module/delegation.rb +11 -20
- data/lib/active_support/core_ext/module/deprecation.rb +2 -2
- data/lib/active_support/core_ext/module/introspection.rb +8 -2
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
- data/lib/active_support/core_ext/module/remove_method.rb +23 -0
- data/lib/active_support/core_ext/module.rb +1 -0
- 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 +78 -77
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +26 -6
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/blank.rb +15 -3
- data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
- data/lib/active_support/core_ext/object/duplicable.rb +7 -12
- data/lib/active_support/core_ext/object/inclusion.rb +2 -2
- data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +15 -7
- data/lib/active_support/core_ext/object/to_query.rb +1 -1
- data/lib/active_support/core_ext/object/try.rb +67 -21
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/object.rb +0 -1
- data/lib/active_support/core_ext/range/conversions.rb +18 -6
- data/lib/active_support/core_ext/range/each.rb +16 -18
- data/lib/active_support/core_ext/range/include_range.rb +20 -20
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +3 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -2
- data/lib/active_support/core_ext/string/inflections.rb +32 -5
- data/lib/active_support/core_ext/string/multibyte.rb +11 -7
- data/lib/active_support/core_ext/string/output_safety.rb +12 -14
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/struct.rb +3 -6
- data/lib/active_support/core_ext/time/calculations.rb +18 -9
- data/lib/active_support/core_ext/time/conversions.rb +4 -2
- data/lib/active_support/core_ext/time/marshal.rb +2 -29
- data/lib/active_support/core_ext/time/zones.rb +36 -4
- data/lib/active_support/core_ext/time.rb +0 -1
- data/lib/active_support/core_ext/uri.rb +1 -3
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/dependencies/interlock.rb +55 -0
- data/lib/active_support/dependencies.rb +88 -95
- data/lib/active_support/deprecation/behaviors.rb +15 -1
- data/lib/active_support/deprecation/instance_delegator.rb +13 -0
- data/lib/active_support/deprecation/method_wrappers.rb +42 -16
- data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
- data/lib/active_support/deprecation/reporting.rb +23 -5
- data/lib/active_support/deprecation.rb +1 -1
- 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 +90 -15
- data/lib/active_support/evented_file_update_checker.rb +199 -0
- data/lib/active_support/execution_wrapper.rb +126 -0
- data/lib/active_support/executor.rb +6 -0
- data/lib/active_support/file_update_checker.rb +23 -3
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/gzip.rb +1 -1
- data/lib/active_support/hash_with_indifferent_access.rb +40 -11
- data/lib/active_support/i18n_railtie.rb +25 -4
- data/lib/active_support/inflector/inflections.rb +36 -5
- data/lib/active_support/inflector/methods.rb +97 -90
- data/lib/active_support/inflector/transliterate.rb +36 -21
- data/lib/active_support/json/decoding.rb +11 -10
- data/lib/active_support/json/encoding.rb +1 -51
- data/lib/active_support/key_generator.rb +7 -9
- data/lib/active_support/lazy_load_hooks.rb +46 -18
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +3 -3
- data/lib/active_support/log_subscriber.rb +1 -1
- data/lib/active_support/logger.rb +3 -4
- data/lib/active_support/logger_silence.rb +2 -1
- data/lib/active_support/logger_thread_safe_level.rb +2 -3
- data/lib/active_support/message_encryptor.rb +7 -7
- data/lib/active_support/message_verifier.rb +70 -8
- data/lib/active_support/multibyte/chars.rb +12 -3
- data/lib/active_support/multibyte/unicode.rb +44 -21
- data/lib/active_support/notifications/fanout.rb +5 -5
- data/lib/active_support/notifications/instrumenter.rb +20 -2
- data/lib/active_support/notifications.rb +2 -2
- data/lib/active_support/number_helper/number_to_currency_converter.rb +7 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +8 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -2
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +11 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +30 -25
- data/lib/active_support/number_helper.rb +90 -67
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +15 -1
- data/lib/active_support/per_thread_registry.rb +3 -0
- data/lib/active_support/rails.rb +2 -2
- data/lib/active_support/railtie.rb +6 -1
- data/lib/active_support/reloader.rb +129 -0
- data/lib/active_support/rescuable.rb +101 -47
- data/lib/active_support/string_inquirer.rb +1 -1
- data/lib/active_support/subscriber.rb +5 -10
- data/lib/active_support/tagged_logging.rb +8 -7
- data/lib/active_support/test_case.rb +17 -29
- data/lib/active_support/testing/assertions.rb +15 -13
- data/lib/active_support/testing/deprecation.rb +9 -8
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +22 -8
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/time_helpers.rb +3 -1
- data/lib/active_support/time_with_zone.rb +123 -33
- data/lib/active_support/values/time_zone.rb +101 -47
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support.rb +11 -6
- metadata +36 -17
- 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/object/itself.rb +0 -15
- data/lib/active_support/core_ext/thread.rb +0 -86
@@ -7,12 +7,21 @@ class Module
|
|
7
7
|
# m = Module.new
|
8
8
|
# m.name # => nil
|
9
9
|
#
|
10
|
+
# +anonymous?+ method returns true if module does not have a name, false otherwise:
|
11
|
+
#
|
12
|
+
# Module.new.anonymous? # => true
|
13
|
+
#
|
14
|
+
# module M; end
|
15
|
+
# M.anonymous? # => false
|
16
|
+
#
|
10
17
|
# A module gets a name when it is first assigned to a constant. Either
|
11
18
|
# via the +module+ or +class+ keyword or by an explicit assignment:
|
12
19
|
#
|
13
20
|
# m = Module.new # creates an anonymous module
|
14
|
-
#
|
21
|
+
# m.anonymous? # => true
|
22
|
+
# M = m # m gets a name here as a side-effect
|
15
23
|
# m.name # => "M"
|
24
|
+
# m.anonymous? # => false
|
16
25
|
def anonymous?
|
17
26
|
name.nil?
|
18
27
|
end
|
@@ -27,11 +27,8 @@ class Module
|
|
27
27
|
|
28
28
|
def attr_internal_define(attr_name, type)
|
29
29
|
internal_name = attr_internal_ivar_name(attr_name).sub(/\A@/, '')
|
30
|
-
#
|
31
|
-
|
32
|
-
# use native attr_* methods as they are faster on some Ruby implementations
|
33
|
-
send("attr_#{type}", internal_name)
|
34
|
-
end
|
30
|
+
# use native attr_* methods as they are faster on some Ruby implementations
|
31
|
+
send("attr_#{type}", internal_name)
|
35
32
|
attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer
|
36
33
|
alias_method attr_name, internal_name
|
37
34
|
remove_method internal_name
|
@@ -5,7 +5,7 @@ require 'active_support/core_ext/array/extract_options'
|
|
5
5
|
# attributes.
|
6
6
|
class Module
|
7
7
|
# Defines a class attribute and creates a class and instance reader methods.
|
8
|
-
# The underlying
|
8
|
+
# The underlying class variable is set to +nil+, if it is not previously
|
9
9
|
# defined.
|
10
10
|
#
|
11
11
|
# module HairColors
|
@@ -19,15 +19,15 @@ class Module
|
|
19
19
|
# The attribute name must be a valid method name in Ruby.
|
20
20
|
#
|
21
21
|
# module Foo
|
22
|
-
# mattr_reader :"1_Badname
|
22
|
+
# mattr_reader :"1_Badname"
|
23
23
|
# end
|
24
|
-
# # => NameError: invalid attribute name
|
24
|
+
# # => NameError: invalid attribute name: 1_Badname
|
25
25
|
#
|
26
26
|
# If you want to opt out the creation on the instance reader method, pass
|
27
27
|
# <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
|
28
28
|
#
|
29
29
|
# module HairColors
|
30
|
-
#
|
30
|
+
# mattr_reader :hair_colors, instance_reader: false
|
31
31
|
# end
|
32
32
|
#
|
33
33
|
# class Person
|
@@ -40,7 +40,7 @@ class Module
|
|
40
40
|
# Also, you can pass a block to set up the attribute with a default value.
|
41
41
|
#
|
42
42
|
# module HairColors
|
43
|
-
#
|
43
|
+
# mattr_reader :hair_colors do
|
44
44
|
# [:brown, :black, :blonde, :red]
|
45
45
|
# end
|
46
46
|
# end
|
@@ -49,11 +49,11 @@ class Module
|
|
49
49
|
# include HairColors
|
50
50
|
# end
|
51
51
|
#
|
52
|
-
# Person.hair_colors # => [:brown, :black, :blonde, :red]
|
52
|
+
# Person.new.hair_colors # => [:brown, :black, :blonde, :red]
|
53
53
|
def mattr_reader(*syms)
|
54
54
|
options = syms.extract_options!
|
55
55
|
syms.each do |sym|
|
56
|
-
raise NameError.new("invalid attribute name: #{sym}") unless sym =~
|
56
|
+
raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /\A[_A-Za-z]\w*\z/
|
57
57
|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
58
58
|
@@#{sym} = nil unless defined? @@#{sym}
|
59
59
|
|
@@ -105,7 +105,7 @@ class Module
|
|
105
105
|
#
|
106
106
|
# Also, you can pass a block to set up the attribute with a default value.
|
107
107
|
#
|
108
|
-
#
|
108
|
+
# module HairColors
|
109
109
|
# mattr_writer :hair_colors do
|
110
110
|
# [:brown, :black, :blonde, :red]
|
111
111
|
# end
|
@@ -119,7 +119,7 @@ class Module
|
|
119
119
|
def mattr_writer(*syms)
|
120
120
|
options = syms.extract_options!
|
121
121
|
syms.each do |sym|
|
122
|
-
raise NameError.new("invalid attribute name: #{sym}") unless sym =~
|
122
|
+
raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /\A[_A-Za-z]\w*\z/
|
123
123
|
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
124
124
|
@@#{sym} = nil unless defined? @@#{sym}
|
125
125
|
|
@@ -150,8 +150,8 @@ class Module
|
|
150
150
|
# include HairColors
|
151
151
|
# end
|
152
152
|
#
|
153
|
-
#
|
154
|
-
#
|
153
|
+
# HairColors.hair_colors = [:brown, :black, :blonde, :red]
|
154
|
+
# HairColors.hair_colors # => [:brown, :black, :blonde, :red]
|
155
155
|
# Person.new.hair_colors # => [:brown, :black, :blonde, :red]
|
156
156
|
#
|
157
157
|
# If a subclass changes the value then that would also change the value for
|
@@ -161,8 +161,8 @@ class Module
|
|
161
161
|
# class Male < Person
|
162
162
|
# end
|
163
163
|
#
|
164
|
-
# Male.hair_colors << :blue
|
165
|
-
# Person.hair_colors # => [:brown, :black, :blonde, :red, :blue]
|
164
|
+
# Male.new.hair_colors << :blue
|
165
|
+
# Person.new.hair_colors # => [:brown, :black, :blonde, :red, :blue]
|
166
166
|
#
|
167
167
|
# To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
|
168
168
|
# To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
|
@@ -203,10 +203,10 @@ class Module
|
|
203
203
|
# include HairColors
|
204
204
|
# end
|
205
205
|
#
|
206
|
-
# Person.class_variable_get("@@hair_colors")
|
206
|
+
# Person.class_variable_get("@@hair_colors") # => [:brown, :black, :blonde, :red]
|
207
207
|
def mattr_accessor(*syms, &blk)
|
208
208
|
mattr_reader(*syms, &blk)
|
209
|
-
mattr_writer(*syms
|
209
|
+
mattr_writer(*syms)
|
210
210
|
end
|
211
211
|
alias :cattr_accessor :mattr_accessor
|
212
212
|
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
require 'active_support/core_ext/array/extract_options'
|
2
|
+
|
3
|
+
# Extends the module object with class/module and instance accessors for
|
4
|
+
# class/module attributes, just like the native attr* accessors for instance
|
5
|
+
# attributes, but does so on a per-thread basis.
|
6
|
+
#
|
7
|
+
# So the values are scoped within the Thread.current space under the class name
|
8
|
+
# of the module.
|
9
|
+
class Module
|
10
|
+
# Defines a per-thread class attribute and creates class and instance reader methods.
|
11
|
+
# The underlying per-thread class variable is set to +nil+, if it is not previously defined.
|
12
|
+
#
|
13
|
+
# module Current
|
14
|
+
# thread_mattr_reader :user
|
15
|
+
# end
|
16
|
+
#
|
17
|
+
# Current.user # => nil
|
18
|
+
# Thread.current[:attr_Current_user] = "DHH"
|
19
|
+
# Current.user # => "DHH"
|
20
|
+
#
|
21
|
+
# The attribute name must be a valid method name in Ruby.
|
22
|
+
#
|
23
|
+
# module Foo
|
24
|
+
# thread_mattr_reader :"1_Badname"
|
25
|
+
# end
|
26
|
+
# # => NameError: invalid attribute name: 1_Badname
|
27
|
+
#
|
28
|
+
# If you want to opt out the creation on the instance reader method, pass
|
29
|
+
# <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
|
30
|
+
#
|
31
|
+
# class Current
|
32
|
+
# thread_mattr_reader :user, instance_reader: false
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# Current.new.user # => NoMethodError
|
36
|
+
def thread_mattr_reader(*syms) # :nodoc:
|
37
|
+
options = syms.extract_options!
|
38
|
+
|
39
|
+
syms.each do |sym|
|
40
|
+
raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
|
41
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
42
|
+
def self.#{sym}
|
43
|
+
Thread.current["attr_"+ name + "_#{sym}"]
|
44
|
+
end
|
45
|
+
EOS
|
46
|
+
|
47
|
+
unless options[:instance_reader] == false || options[:instance_accessor] == false
|
48
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
49
|
+
def #{sym}
|
50
|
+
Thread.current["attr_"+ self.class.name + "_#{sym}"]
|
51
|
+
end
|
52
|
+
EOS
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
alias :thread_cattr_reader :thread_mattr_reader
|
57
|
+
|
58
|
+
# Defines a per-thread class attribute and creates a class and instance writer methods to
|
59
|
+
# allow assignment to the attribute.
|
60
|
+
#
|
61
|
+
# module Current
|
62
|
+
# thread_mattr_writer :user
|
63
|
+
# end
|
64
|
+
#
|
65
|
+
# Current.user = "DHH"
|
66
|
+
# Thread.current[:attr_Current_user] # => "DHH"
|
67
|
+
#
|
68
|
+
# If you want to opt out the instance writer method, pass
|
69
|
+
# <tt>instance_writer: false</tt> or <tt>instance_accessor: false</tt>.
|
70
|
+
#
|
71
|
+
# class Current
|
72
|
+
# thread_mattr_writer :user, instance_writer: false
|
73
|
+
# end
|
74
|
+
#
|
75
|
+
# Current.new.user = "DHH" # => NoMethodError
|
76
|
+
def thread_mattr_writer(*syms) # :nodoc:
|
77
|
+
options = syms.extract_options!
|
78
|
+
syms.each do |sym|
|
79
|
+
raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
|
80
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
81
|
+
def self.#{sym}=(obj)
|
82
|
+
Thread.current["attr_"+ name + "_#{sym}"] = obj
|
83
|
+
end
|
84
|
+
EOS
|
85
|
+
|
86
|
+
unless options[:instance_writer] == false || options[:instance_accessor] == false
|
87
|
+
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
88
|
+
def #{sym}=(obj)
|
89
|
+
Thread.current["attr_"+ self.class.name + "_#{sym}"] = obj
|
90
|
+
end
|
91
|
+
EOS
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
alias :thread_cattr_writer :thread_mattr_writer
|
96
|
+
|
97
|
+
# Defines both class and instance accessors for class attributes.
|
98
|
+
#
|
99
|
+
# class Account
|
100
|
+
# thread_mattr_accessor :user
|
101
|
+
# end
|
102
|
+
#
|
103
|
+
# Account.user = "DHH"
|
104
|
+
# Account.user # => "DHH"
|
105
|
+
# Account.new.user # => "DHH"
|
106
|
+
#
|
107
|
+
# If a subclass changes the value, the parent class' value is not changed.
|
108
|
+
# Similarly, if the parent class changes the value, the value of subclasses
|
109
|
+
# is not changed.
|
110
|
+
#
|
111
|
+
# class Customer < Account
|
112
|
+
# end
|
113
|
+
#
|
114
|
+
# Customer.user = "Rafael"
|
115
|
+
# Customer.user # => "Rafael"
|
116
|
+
# Account.user # => "DHH"
|
117
|
+
#
|
118
|
+
# To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
|
119
|
+
# To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
|
120
|
+
#
|
121
|
+
# class Current
|
122
|
+
# thread_mattr_accessor :user, instance_writer: false, instance_reader: false
|
123
|
+
# end
|
124
|
+
#
|
125
|
+
# Current.new.user = "DHH" # => NoMethodError
|
126
|
+
# Current.new.user # => NoMethodError
|
127
|
+
#
|
128
|
+
# Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
|
129
|
+
#
|
130
|
+
# class Current
|
131
|
+
# mattr_accessor :user, instance_accessor: false
|
132
|
+
# end
|
133
|
+
#
|
134
|
+
# Current.new.user = "DHH" # => NoMethodError
|
135
|
+
# Current.new.user # => NoMethodError
|
136
|
+
def thread_mattr_accessor(*syms, &blk)
|
137
|
+
thread_mattr_reader(*syms, &blk)
|
138
|
+
thread_mattr_writer(*syms, &blk)
|
139
|
+
end
|
140
|
+
alias :thread_cattr_accessor :thread_mattr_accessor
|
141
|
+
end
|
@@ -63,10 +63,10 @@ class Module
|
|
63
63
|
#
|
64
64
|
# == Mix-in noise exiled to its own file:
|
65
65
|
#
|
66
|
-
# Once our chunk of behavior starts pushing the scroll-to-understand
|
66
|
+
# Once our chunk of behavior starts pushing the scroll-to-understand-it
|
67
67
|
# boundary, we give in and move it to a separate file. At this size, the
|
68
|
-
# overhead
|
69
|
-
#
|
68
|
+
# increased overhead can be a reasonable tradeoff even if it reduces our
|
69
|
+
# at-a-glance perception of how things work.
|
70
70
|
#
|
71
71
|
# class Todo
|
72
72
|
# # Other todo implementation
|
@@ -99,7 +99,7 @@ class Module
|
|
99
99
|
# end
|
100
100
|
#
|
101
101
|
# Todo.ancestors
|
102
|
-
# # => Todo, Todo::EventTracking, Object
|
102
|
+
# # => [Todo, Todo::EventTracking, Object]
|
103
103
|
#
|
104
104
|
# This small step has some wonderful ripple effects. We can
|
105
105
|
# * grok the behavior of our class in one glance,
|
@@ -5,18 +5,12 @@ class Module
|
|
5
5
|
# option is not used.
|
6
6
|
class DelegationError < NoMethodError; end
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
).freeze
|
13
|
-
|
14
|
-
DELEGATION_RESERVED_KEYWORDS = Set.new(
|
15
|
-
%w(_ arg args block)
|
16
|
-
)
|
17
|
-
|
8
|
+
RUBY_RESERVED_KEYWORDS = %w(alias and BEGIN begin break case class def defined? do
|
9
|
+
else elsif END end ensure false for if in module next nil not or redo rescue retry
|
10
|
+
return self super then true undef unless until when while yield)
|
11
|
+
DELEGATION_RESERVED_KEYWORDS = %w(_ arg args block)
|
18
12
|
DELEGATION_RESERVED_METHOD_NAMES = Set.new(
|
19
|
-
|
13
|
+
RUBY_RESERVED_KEYWORDS + DELEGATION_RESERVED_KEYWORDS
|
20
14
|
).freeze
|
21
15
|
|
22
16
|
# Provides a +delegate+ class method to easily expose contained objects'
|
@@ -25,7 +19,7 @@ class Module
|
|
25
19
|
# ==== Options
|
26
20
|
# * <tt>:to</tt> - Specifies the target object
|
27
21
|
# * <tt>:prefix</tt> - Prefixes the new method with the target name or a custom prefix
|
28
|
-
# * <tt>:allow_nil</tt> - if set to true, prevents a +NoMethodError+
|
22
|
+
# * <tt>:allow_nil</tt> - if set to true, prevents a +NoMethodError+ from being raised
|
29
23
|
#
|
30
24
|
# The macro receives one or more method names (specified as symbols or
|
31
25
|
# strings) and the name of the target object via the <tt>:to</tt> option
|
@@ -156,14 +150,11 @@ class Module
|
|
156
150
|
#
|
157
151
|
# The target method must be public, otherwise it will raise +NoMethodError+.
|
158
152
|
#
|
159
|
-
def delegate(*methods)
|
160
|
-
|
161
|
-
unless options.is_a?(Hash) && to = options[:to]
|
153
|
+
def delegate(*methods, to: nil, prefix: nil, allow_nil: nil)
|
154
|
+
unless to
|
162
155
|
raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).'
|
163
156
|
end
|
164
157
|
|
165
|
-
prefix, allow_nil = options.values_at(:prefix, :allow_nil)
|
166
|
-
|
167
158
|
if prefix == true && to =~ /^[^a-z_]/
|
168
159
|
raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
|
169
160
|
end
|
@@ -175,11 +166,11 @@ class Module
|
|
175
166
|
''
|
176
167
|
end
|
177
168
|
|
178
|
-
|
179
|
-
line =
|
169
|
+
location = caller_locations(1, 1).first
|
170
|
+
file, line = location.path, location.lineno
|
180
171
|
|
181
172
|
to = to.to_s
|
182
|
-
to = "self.#{to}" if
|
173
|
+
to = "self.#{to}" if DELEGATION_RESERVED_METHOD_NAMES.include?(to)
|
183
174
|
|
184
175
|
methods.each do |method|
|
185
176
|
# Attribute writer methods only accept one argument. Makes sure []=
|
@@ -13,8 +13,8 @@ class Module
|
|
13
13
|
#
|
14
14
|
# class MyLib::Deprecator
|
15
15
|
# def deprecation_warning(deprecated_method_name, message, caller_backtrace = nil)
|
16
|
-
#
|
17
|
-
#
|
16
|
+
# message = "#{deprecated_method_name} is deprecated and will be removed from MyLibrary | #{message}"
|
17
|
+
# Kernel.warn message
|
18
18
|
# end
|
19
19
|
# end
|
20
20
|
def deprecate(*method_names)
|
@@ -5,10 +5,12 @@ class Module
|
|
5
5
|
#
|
6
6
|
# M::N.parent_name # => "M"
|
7
7
|
def parent_name
|
8
|
-
if defined?
|
8
|
+
if defined?(@parent_name)
|
9
9
|
@parent_name
|
10
10
|
else
|
11
|
-
|
11
|
+
parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
|
12
|
+
@parent_name = parent_name unless frozen?
|
13
|
+
parent_name
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
@@ -57,6 +59,10 @@ class Module
|
|
57
59
|
end
|
58
60
|
|
59
61
|
def local_constants #:nodoc:
|
62
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
63
|
+
Module#local_constants is deprecated and will be removed in Rails 5.1.
|
64
|
+
Use Module#constants(false) instead.
|
65
|
+
MSG
|
60
66
|
constants(false)
|
61
67
|
end
|
62
68
|
end
|
@@ -1,13 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
def methods_transplantable? # :nodoc:
|
5
|
-
x = Module.new {
|
6
|
-
def foo; end # :nodoc:
|
7
|
-
}
|
8
|
-
Module.new { define_method :bar, x.instance_method(:foo) }
|
9
|
-
true
|
10
|
-
rescue TypeError
|
11
|
-
false
|
12
|
-
end
|
13
|
-
end
|
1
|
+
require 'active_support/deprecation'
|
2
|
+
|
3
|
+
ActiveSupport::Deprecation.warn("This file is deprecated and will be removed in Rails 5.1 with no replacement.")
|
@@ -3,13 +3,16 @@ require 'active_support/core_ext/string/inflections'
|
|
3
3
|
#--
|
4
4
|
# Allows code reuse in the methods below without polluting Module.
|
5
5
|
#++
|
6
|
-
module QualifiedConstUtils
|
7
|
-
def self.raise_if_absolute(path)
|
8
|
-
raise NameError.new("wrong constant name #$&") if path =~ /\A::[^:]+/
|
9
|
-
end
|
10
6
|
|
11
|
-
|
12
|
-
|
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
|
13
16
|
end
|
14
17
|
end
|
15
18
|
|
@@ -24,9 +27,14 @@ end
|
|
24
27
|
#++
|
25
28
|
class Module
|
26
29
|
def qualified_const_defined?(path, search_parents=true)
|
27
|
-
|
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
|
28
34
|
|
29
|
-
QualifiedConstUtils.
|
35
|
+
ActiveSupport::QualifiedConstUtils.raise_if_absolute(path)
|
36
|
+
|
37
|
+
ActiveSupport::QualifiedConstUtils.names(path).inject(self) do |mod, name|
|
30
38
|
return unless mod.const_defined?(name, search_parents)
|
31
39
|
mod.const_get(name)
|
32
40
|
end
|
@@ -34,19 +42,29 @@ class Module
|
|
34
42
|
end
|
35
43
|
|
36
44
|
def qualified_const_get(path)
|
37
|
-
|
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)
|
38
51
|
|
39
|
-
QualifiedConstUtils.names(path).inject(self) do |mod, name|
|
52
|
+
ActiveSupport::QualifiedConstUtils.names(path).inject(self) do |mod, name|
|
40
53
|
mod.const_get(name)
|
41
54
|
end
|
42
55
|
end
|
43
56
|
|
44
57
|
def qualified_const_set(path, value)
|
45
|
-
|
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)
|
46
64
|
|
47
65
|
const_name = path.demodulize
|
48
66
|
mod_name = path.deconstantize
|
49
|
-
mod = mod_name.empty? ? self :
|
67
|
+
mod = mod_name.empty? ? self : const_get(mod_name)
|
50
68
|
mod.const_set(const_name, value)
|
51
69
|
end
|
52
70
|
end
|
@@ -1,12 +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
7
|
end
|
7
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.
|
8
18
|
def redefine_method(method, &block)
|
19
|
+
visibility = method_visibility(method)
|
9
20
|
remove_possible_method(method)
|
10
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
|
11
34
|
end
|
12
35
|
end
|
@@ -3,6 +3,7 @@ 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
8
|
require 'active_support/core_ext/module/concerning'
|
8
9
|
require 'active_support/core_ext/module/delegation'
|
@@ -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
|