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.

Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +678 -348
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +2 -3
  5. data/lib/active_support/array_inquirer.rb +44 -0
  6. data/lib/active_support/backtrace_cleaner.rb +1 -1
  7. data/lib/active_support/benchmarkable.rb +1 -1
  8. data/lib/active_support/cache/file_store.rb +36 -22
  9. data/lib/active_support/cache/mem_cache_store.rb +63 -54
  10. data/lib/active_support/cache/memory_store.rb +16 -21
  11. data/lib/active_support/cache/null_store.rb +1 -4
  12. data/lib/active_support/cache/strategy/local_cache.rb +31 -20
  13. data/lib/active_support/cache/strategy/local_cache_middleware.rb +4 -4
  14. data/lib/active_support/cache.rb +71 -87
  15. data/lib/active_support/callbacks.rb +109 -113
  16. data/lib/active_support/concern.rb +1 -1
  17. data/lib/active_support/concurrency/latch.rb +11 -12
  18. data/lib/active_support/concurrency/share_lock.rb +226 -0
  19. data/lib/active_support/configurable.rb +1 -0
  20. data/lib/active_support/core_ext/array/access.rb +27 -1
  21. data/lib/active_support/core_ext/array/conversions.rb +6 -4
  22. data/lib/active_support/core_ext/array/grouping.rb +9 -18
  23. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  24. data/lib/active_support/core_ext/array/wrap.rb +5 -4
  25. data/lib/active_support/core_ext/array.rb +1 -0
  26. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
  27. data/lib/active_support/core_ext/class/attribute.rb +10 -9
  28. data/lib/active_support/core_ext/class/subclasses.rb +3 -2
  29. data/lib/active_support/core_ext/class.rb +0 -1
  30. data/lib/active_support/core_ext/date/blank.rb +12 -0
  31. data/lib/active_support/core_ext/date/calculations.rb +1 -1
  32. data/lib/active_support/core_ext/date/conversions.rb +7 -6
  33. data/lib/active_support/core_ext/date.rb +1 -1
  34. data/lib/active_support/core_ext/date_and_time/calculations.rb +100 -27
  35. data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -1
  36. data/lib/active_support/core_ext/date_and_time/zones.rb +3 -4
  37. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  38. data/lib/active_support/core_ext/date_time/calculations.rb +14 -8
  39. data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
  40. data/lib/active_support/core_ext/date_time.rb +1 -1
  41. data/lib/active_support/core_ext/enumerable.rb +75 -25
  42. data/lib/active_support/core_ext/file/atomic.rb +30 -25
  43. data/lib/active_support/core_ext/hash/conversions.rb +22 -2
  44. data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
  45. data/lib/active_support/core_ext/hash/except.rb +9 -8
  46. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
  47. data/lib/active_support/core_ext/hash/keys.rb +25 -21
  48. data/lib/active_support/core_ext/hash/slice.rb +1 -1
  49. data/lib/active_support/core_ext/hash/transform_values.rb +11 -5
  50. data/lib/active_support/core_ext/integer/time.rb +2 -2
  51. data/lib/active_support/core_ext/kernel/concern.rb +2 -0
  52. data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
  53. data/lib/active_support/core_ext/kernel/reporting.rb +2 -84
  54. data/lib/active_support/core_ext/kernel.rb +0 -1
  55. data/lib/active_support/core_ext/load_error.rb +5 -2
  56. data/lib/active_support/core_ext/marshal.rb +7 -9
  57. data/lib/active_support/core_ext/module/aliasing.rb +6 -1
  58. data/lib/active_support/core_ext/module/anonymous.rb +10 -1
  59. data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
  60. data/lib/active_support/core_ext/module/attribute_accessors.rb +15 -15
  61. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  62. data/lib/active_support/core_ext/module/concerning.rb +4 -4
  63. data/lib/active_support/core_ext/module/delegation.rb +11 -20
  64. data/lib/active_support/core_ext/module/deprecation.rb +2 -2
  65. data/lib/active_support/core_ext/module/introspection.rb +8 -2
  66. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
  67. data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
  68. data/lib/active_support/core_ext/module/remove_method.rb +23 -0
  69. data/lib/active_support/core_ext/module.rb +1 -0
  70. data/lib/active_support/core_ext/name_error.rb +15 -2
  71. data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
  72. data/lib/active_support/core_ext/numeric/conversions.rb +78 -77
  73. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  74. data/lib/active_support/core_ext/numeric/time.rb +26 -6
  75. data/lib/active_support/core_ext/numeric.rb +1 -0
  76. data/lib/active_support/core_ext/object/blank.rb +15 -3
  77. data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
  78. data/lib/active_support/core_ext/object/duplicable.rb +7 -12
  79. data/lib/active_support/core_ext/object/inclusion.rb +2 -2
  80. data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
  81. data/lib/active_support/core_ext/object/json.rb +15 -7
  82. data/lib/active_support/core_ext/object/to_query.rb +1 -1
  83. data/lib/active_support/core_ext/object/try.rb +67 -21
  84. data/lib/active_support/core_ext/object/with_options.rb +1 -1
  85. data/lib/active_support/core_ext/object.rb +0 -1
  86. data/lib/active_support/core_ext/range/conversions.rb +18 -6
  87. data/lib/active_support/core_ext/range/each.rb +16 -18
  88. data/lib/active_support/core_ext/range/include_range.rb +20 -20
  89. data/lib/active_support/core_ext/securerandom.rb +23 -0
  90. data/lib/active_support/core_ext/string/behavior.rb +1 -1
  91. data/lib/active_support/core_ext/string/conversions.rb +3 -2
  92. data/lib/active_support/core_ext/string/filters.rb +1 -2
  93. data/lib/active_support/core_ext/string/inflections.rb +32 -5
  94. data/lib/active_support/core_ext/string/multibyte.rb +11 -7
  95. data/lib/active_support/core_ext/string/output_safety.rb +12 -14
  96. data/lib/active_support/core_ext/string/strip.rb +3 -6
  97. data/lib/active_support/core_ext/struct.rb +3 -6
  98. data/lib/active_support/core_ext/time/calculations.rb +18 -9
  99. data/lib/active_support/core_ext/time/conversions.rb +4 -2
  100. data/lib/active_support/core_ext/time/marshal.rb +2 -29
  101. data/lib/active_support/core_ext/time/zones.rb +36 -4
  102. data/lib/active_support/core_ext/time.rb +0 -1
  103. data/lib/active_support/core_ext/uri.rb +1 -3
  104. data/lib/active_support/core_ext.rb +2 -1
  105. data/lib/active_support/dependencies/interlock.rb +55 -0
  106. data/lib/active_support/dependencies.rb +88 -95
  107. data/lib/active_support/deprecation/behaviors.rb +15 -1
  108. data/lib/active_support/deprecation/instance_delegator.rb +13 -0
  109. data/lib/active_support/deprecation/method_wrappers.rb +42 -16
  110. data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
  111. data/lib/active_support/deprecation/reporting.rb +23 -5
  112. data/lib/active_support/deprecation.rb +1 -1
  113. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  114. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  115. data/lib/active_support/duration.rb +90 -15
  116. data/lib/active_support/evented_file_update_checker.rb +199 -0
  117. data/lib/active_support/execution_wrapper.rb +126 -0
  118. data/lib/active_support/executor.rb +6 -0
  119. data/lib/active_support/file_update_checker.rb +23 -3
  120. data/lib/active_support/gem_version.rb +5 -5
  121. data/lib/active_support/gzip.rb +1 -1
  122. data/lib/active_support/hash_with_indifferent_access.rb +40 -11
  123. data/lib/active_support/i18n_railtie.rb +25 -4
  124. data/lib/active_support/inflector/inflections.rb +36 -5
  125. data/lib/active_support/inflector/methods.rb +97 -90
  126. data/lib/active_support/inflector/transliterate.rb +36 -21
  127. data/lib/active_support/json/decoding.rb +11 -10
  128. data/lib/active_support/json/encoding.rb +1 -51
  129. data/lib/active_support/key_generator.rb +7 -9
  130. data/lib/active_support/lazy_load_hooks.rb +46 -18
  131. data/lib/active_support/locale/en.yml +2 -0
  132. data/lib/active_support/log_subscriber/test_helper.rb +3 -3
  133. data/lib/active_support/log_subscriber.rb +1 -1
  134. data/lib/active_support/logger.rb +3 -4
  135. data/lib/active_support/logger_silence.rb +2 -1
  136. data/lib/active_support/logger_thread_safe_level.rb +2 -3
  137. data/lib/active_support/message_encryptor.rb +7 -7
  138. data/lib/active_support/message_verifier.rb +70 -8
  139. data/lib/active_support/multibyte/chars.rb +12 -3
  140. data/lib/active_support/multibyte/unicode.rb +44 -21
  141. data/lib/active_support/notifications/fanout.rb +5 -5
  142. data/lib/active_support/notifications/instrumenter.rb +20 -2
  143. data/lib/active_support/notifications.rb +2 -2
  144. data/lib/active_support/number_helper/number_to_currency_converter.rb +7 -9
  145. data/lib/active_support/number_helper/number_to_delimited_converter.rb +8 -3
  146. data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
  147. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -2
  148. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  149. data/lib/active_support/number_helper/number_to_phone_converter.rb +11 -2
  150. data/lib/active_support/number_helper/number_to_rounded_converter.rb +30 -25
  151. data/lib/active_support/number_helper.rb +90 -67
  152. data/lib/active_support/ordered_hash.rb +1 -1
  153. data/lib/active_support/ordered_options.rb +15 -1
  154. data/lib/active_support/per_thread_registry.rb +3 -0
  155. data/lib/active_support/rails.rb +2 -2
  156. data/lib/active_support/railtie.rb +6 -1
  157. data/lib/active_support/reloader.rb +129 -0
  158. data/lib/active_support/rescuable.rb +101 -47
  159. data/lib/active_support/string_inquirer.rb +1 -1
  160. data/lib/active_support/subscriber.rb +5 -10
  161. data/lib/active_support/tagged_logging.rb +8 -7
  162. data/lib/active_support/test_case.rb +17 -29
  163. data/lib/active_support/testing/assertions.rb +15 -13
  164. data/lib/active_support/testing/deprecation.rb +9 -8
  165. data/lib/active_support/testing/file_fixtures.rb +34 -0
  166. data/lib/active_support/testing/isolation.rb +22 -8
  167. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  168. data/lib/active_support/testing/stream.rb +42 -0
  169. data/lib/active_support/testing/time_helpers.rb +3 -1
  170. data/lib/active_support/time_with_zone.rb +123 -33
  171. data/lib/active_support/values/time_zone.rb +101 -47
  172. data/lib/active_support/values/unicode_tables.dat +0 -0
  173. data/lib/active_support/xml_mini/jdom.rb +1 -1
  174. data/lib/active_support/xml_mini/libxml.rb +2 -2
  175. data/lib/active_support/xml_mini/nokogiri.rb +2 -2
  176. data/lib/active_support.rb +11 -6
  177. metadata +36 -17
  178. data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
  179. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
  180. data/lib/active_support/core_ext/date_time/zones.rb +0 -6
  181. data/lib/active_support/core_ext/object/itself.rb +0 -15
  182. 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
- # M = m # => m gets a name here as a side-effect
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
- # class_eval is necessary on 1.9 or else the methods are made private
31
- class_eval do
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 the class variable is set to +nil+, if it is not previously
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
- # mattr_writer :hair_colors, instance_reader: false
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
- # cattr_reader :hair_colors do
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 =~ /^[_A-Za-z]\w*$/
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
- # class HairColors
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 =~ /^[_A-Za-z]\w*$/
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
- # Person.hair_colors = [:brown, :black, :blonde, :red]
154
- # Person.hair_colors # => [:brown, :black, :blonde, :red]
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") #=> [:brown, :black, :blonde, :red]
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, &blk)
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 it's
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 feels in good proportion to the size of our extraction, despite
69
- # diluting our at-a-glance sense of how things really work.
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
- RUBY_RESERVED_WORDS = Set.new(
9
- %w(alias and BEGIN begin break case class def defined? do else elsif END
10
- end ensure false for if in module next nil not or redo rescue retry
11
- return self super then true undef unless until when while yield)
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
- RUBY_RESERVED_WORDS + DELEGATION_RESERVED_KEYWORDS
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+ to be raised
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
- options = methods.pop
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
- file, line = caller.first.split(':', 2)
179
- line = line.to_i
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 RUBY_RESERVED_WORDS.include?(to)
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
- # message = "#{deprecated_method_name} is deprecated and will be removed from MyLibrary | #{message}"
17
- # Kernel.warn message
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? @parent_name
8
+ if defined?(@parent_name)
9
9
  @parent_name
10
10
  else
11
- @parent_name = name =~ /::[^:]+\Z/ ? $`.freeze : nil
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
- class Module
2
- ###
3
- # TODO: remove this after 1.9 support is dropped
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
- def self.names(path)
12
- path.split('::')
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
- QualifiedConstUtils.raise_if_absolute(path)
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.names(path).inject(self) do |mod, name|
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
- QualifiedConstUtils.raise_if_absolute(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)
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
- QualifiedConstUtils.raise_if_absolute(path)
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 : qualified_const_get(mod_name)
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
- last_name = (missing_name || '').split('::').last
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