activesupport 5.0.7.2 → 5.1.7

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 (211) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +464 -694
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/active_support.rb +8 -4
  6. data/lib/active_support/all.rb +3 -3
  7. data/lib/active_support/array_inquirer.rb +7 -5
  8. data/lib/active_support/backtrace_cleaner.rb +4 -4
  9. data/lib/active_support/benchmarkable.rb +3 -3
  10. data/lib/active_support/builder.rb +1 -1
  11. data/lib/active_support/cache.rb +41 -48
  12. data/lib/active_support/cache/file_store.rb +11 -20
  13. data/lib/active_support/cache/mem_cache_store.rb +30 -40
  14. data/lib/active_support/cache/memory_store.rb +13 -13
  15. data/lib/active_support/cache/null_store.rb +4 -4
  16. data/lib/active_support/cache/strategy/local_cache.rb +13 -22
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +4 -5
  18. data/lib/active_support/callbacks.rb +649 -584
  19. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
  20. data/lib/active_support/concurrency/share_lock.rb +20 -21
  21. data/lib/active_support/configurable.rb +5 -5
  22. data/lib/active_support/core_ext.rb +1 -2
  23. data/lib/active_support/core_ext/array.rb +7 -7
  24. data/lib/active_support/core_ext/array/access.rb +1 -1
  25. data/lib/active_support/core_ext/array/conversions.rb +15 -15
  26. data/lib/active_support/core_ext/array/grouping.rb +1 -1
  27. data/lib/active_support/core_ext/array/inquiry.rb +1 -1
  28. data/lib/active_support/core_ext/array/prepend_and_append.rb +1 -1
  29. data/lib/active_support/core_ext/benchmark.rb +1 -1
  30. data/lib/active_support/core_ext/big_decimal.rb +1 -1
  31. data/lib/active_support/core_ext/big_decimal/conversions.rb +4 -6
  32. data/lib/active_support/core_ext/class.rb +2 -2
  33. data/lib/active_support/core_ext/class/attribute.rb +5 -5
  34. data/lib/active_support/core_ext/class/attribute_accessors.rb +1 -1
  35. data/lib/active_support/core_ext/class/subclasses.rb +18 -4
  36. data/lib/active_support/core_ext/date.rb +5 -5
  37. data/lib/active_support/core_ext/date/acts_like.rb +1 -1
  38. data/lib/active_support/core_ext/date/blank.rb +1 -1
  39. data/lib/active_support/core_ext/date/calculations.rb +8 -8
  40. data/lib/active_support/core_ext/date/conversions.rb +12 -12
  41. data/lib/active_support/core_ext/date/zones.rb +2 -2
  42. data/lib/active_support/core_ext/date_and_time/calculations.rb +27 -22
  43. data/lib/active_support/core_ext/date_and_time/compatibility.rb +1 -1
  44. data/lib/active_support/core_ext/date_and_time/zones.rb +7 -8
  45. data/lib/active_support/core_ext/date_time.rb +5 -5
  46. data/lib/active_support/core_ext/date_time/acts_like.rb +2 -2
  47. data/lib/active_support/core_ext/date_time/blank.rb +1 -1
  48. data/lib/active_support/core_ext/date_time/calculations.rb +20 -10
  49. data/lib/active_support/core_ext/date_time/compatibility.rb +2 -2
  50. data/lib/active_support/core_ext/date_time/conversions.rb +12 -12
  51. data/lib/active_support/core_ext/digest/uuid.rb +4 -4
  52. data/lib/active_support/core_ext/enumerable.rb +23 -12
  53. data/lib/active_support/core_ext/file.rb +1 -1
  54. data/lib/active_support/core_ext/file/atomic.rb +4 -4
  55. data/lib/active_support/core_ext/hash.rb +9 -9
  56. data/lib/active_support/core_ext/hash/compact.rb +12 -9
  57. data/lib/active_support/core_ext/hash/conversions.rb +36 -37
  58. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -2
  59. data/lib/active_support/core_ext/hash/keys.rb +6 -6
  60. data/lib/active_support/core_ext/hash/reverse_merge.rb +1 -1
  61. data/lib/active_support/core_ext/hash/slice.rb +4 -4
  62. data/lib/active_support/core_ext/hash/transform_values.rb +1 -0
  63. data/lib/active_support/core_ext/integer.rb +3 -3
  64. data/lib/active_support/core_ext/integer/inflections.rb +1 -1
  65. data/lib/active_support/core_ext/integer/time.rb +2 -2
  66. data/lib/active_support/core_ext/kernel.rb +4 -4
  67. data/lib/active_support/core_ext/kernel/concern.rb +1 -1
  68. data/lib/active_support/core_ext/kernel/reporting.rb +1 -1
  69. data/lib/active_support/core_ext/load_error.rb +1 -18
  70. data/lib/active_support/core_ext/module.rb +11 -12
  71. data/lib/active_support/core_ext/module/aliasing.rb +3 -48
  72. data/lib/active_support/core_ext/module/attr_internal.rb +4 -4
  73. data/lib/active_support/core_ext/module/attribute_accessors.rb +11 -5
  74. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +20 -13
  75. data/lib/active_support/core_ext/module/concerning.rb +1 -1
  76. data/lib/active_support/core_ext/module/delegation.rb +85 -16
  77. data/lib/active_support/core_ext/module/introspection.rb +3 -11
  78. data/lib/active_support/core_ext/module/reachable.rb +2 -2
  79. data/lib/active_support/core_ext/numeric.rb +4 -4
  80. data/lib/active_support/core_ext/numeric/conversions.rb +3 -9
  81. data/lib/active_support/core_ext/numeric/inquiry.rb +21 -21
  82. data/lib/active_support/core_ext/numeric/time.rb +5 -5
  83. data/lib/active_support/core_ext/object.rb +12 -12
  84. data/lib/active_support/core_ext/object/blank.rb +3 -1
  85. data/lib/active_support/core_ext/object/conversions.rb +4 -4
  86. data/lib/active_support/core_ext/object/deep_dup.rb +1 -1
  87. data/lib/active_support/core_ext/object/duplicable.rb +34 -4
  88. data/lib/active_support/core_ext/object/inclusion.rb +1 -1
  89. data/lib/active_support/core_ext/object/json.rb +26 -12
  90. data/lib/active_support/core_ext/object/to_param.rb +1 -1
  91. data/lib/active_support/core_ext/object/to_query.rb +8 -5
  92. data/lib/active_support/core_ext/object/try.rb +1 -1
  93. data/lib/active_support/core_ext/object/with_options.rb +12 -1
  94. data/lib/active_support/core_ext/range.rb +4 -4
  95. data/lib/active_support/core_ext/range/conversions.rb +1 -1
  96. data/lib/active_support/core_ext/regexp.rb +4 -0
  97. data/lib/active_support/core_ext/securerandom.rb +3 -3
  98. data/lib/active_support/core_ext/string.rb +13 -13
  99. data/lib/active_support/core_ext/string/access.rb +6 -6
  100. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  101. data/lib/active_support/core_ext/string/filters.rb +3 -3
  102. data/lib/active_support/core_ext/string/indent.rb +4 -4
  103. data/lib/active_support/core_ext/string/inflections.rb +10 -14
  104. data/lib/active_support/core_ext/string/inquiry.rb +1 -1
  105. data/lib/active_support/core_ext/string/multibyte.rb +1 -1
  106. data/lib/active_support/core_ext/string/output_safety.rb +19 -20
  107. data/lib/active_support/core_ext/string/strip.rb +1 -1
  108. data/lib/active_support/core_ext/string/zones.rb +2 -2
  109. data/lib/active_support/core_ext/time.rb +5 -5
  110. data/lib/active_support/core_ext/time/acts_like.rb +1 -1
  111. data/lib/active_support/core_ext/time/calculations.rb +46 -29
  112. data/lib/active_support/core_ext/time/conversions.rb +15 -12
  113. data/lib/active_support/core_ext/time/zones.rb +3 -3
  114. data/lib/active_support/core_ext/uri.rb +2 -2
  115. data/lib/active_support/dependencies.rb +45 -46
  116. data/lib/active_support/dependencies/interlock.rb +1 -1
  117. data/lib/active_support/deprecation.rb +9 -8
  118. data/lib/active_support/deprecation/behaviors.rb +3 -3
  119. data/lib/active_support/deprecation/constant_accessor.rb +50 -0
  120. data/lib/active_support/deprecation/instance_delegator.rb +2 -2
  121. data/lib/active_support/deprecation/method_wrappers.rb +10 -3
  122. data/lib/active_support/deprecation/proxy_wrappers.rb +6 -4
  123. data/lib/active_support/deprecation/reporting.rb +7 -7
  124. data/lib/active_support/duration.rb +221 -28
  125. data/lib/active_support/duration/iso8601_parser.rb +66 -65
  126. data/lib/active_support/duration/iso8601_serializer.rb +11 -9
  127. data/lib/active_support/evented_file_update_checker.rb +59 -55
  128. data/lib/active_support/execution_wrapper.rb +3 -3
  129. data/lib/active_support/executor.rb +1 -1
  130. data/lib/active_support/file_update_checker.rb +54 -50
  131. data/lib/active_support/gem_version.rb +2 -2
  132. data/lib/active_support/gzip.rb +4 -4
  133. data/lib/active_support/hash_with_indifferent_access.rb +40 -28
  134. data/lib/active_support/i18n.rb +5 -5
  135. data/lib/active_support/i18n_railtie.rb +14 -9
  136. data/lib/active_support/inflections.rb +11 -11
  137. data/lib/active_support/inflector.rb +5 -5
  138. data/lib/active_support/inflector/inflections.rb +11 -9
  139. data/lib/active_support/inflector/methods.rb +52 -51
  140. data/lib/active_support/inflector/transliterate.rb +8 -11
  141. data/lib/active_support/json.rb +2 -2
  142. data/lib/active_support/json/decoding.rb +3 -3
  143. data/lib/active_support/json/encoding.rb +8 -7
  144. data/lib/active_support/key_generator.rb +17 -17
  145. data/lib/active_support/lazy_load_hooks.rb +2 -2
  146. data/lib/active_support/log_subscriber.rb +9 -7
  147. data/lib/active_support/log_subscriber/test_helper.rb +9 -9
  148. data/lib/active_support/logger.rb +3 -3
  149. data/lib/active_support/logger_silence.rb +3 -3
  150. data/lib/active_support/logger_thread_safe_level.rb +1 -1
  151. data/lib/active_support/message_encryptor.rb +77 -35
  152. data/lib/active_support/message_verifier.rb +7 -7
  153. data/lib/active_support/multibyte.rb +2 -2
  154. data/lib/active_support/multibyte/chars.rb +23 -21
  155. data/lib/active_support/multibyte/unicode.rb +68 -89
  156. data/lib/active_support/notifications.rb +7 -5
  157. data/lib/active_support/notifications/fanout.rb +3 -3
  158. data/lib/active_support/notifications/instrumenter.rb +5 -5
  159. data/lib/active_support/number_helper.rb +5 -4
  160. data/lib/active_support/number_helper/number_converter.rb +11 -11
  161. data/lib/active_support/number_helper/number_to_currency_converter.rb +3 -3
  162. data/lib/active_support/number_helper/number_to_delimited_converter.rb +1 -2
  163. data/lib/active_support/number_helper/number_to_human_converter.rb +8 -10
  164. data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -11
  165. data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
  166. data/lib/active_support/number_helper/number_to_phone_converter.rb +1 -3
  167. data/lib/active_support/number_helper/number_to_rounded_converter.rb +12 -32
  168. data/lib/active_support/number_helper/rounding_helper.rb +64 -0
  169. data/lib/active_support/option_merger.rb +1 -1
  170. data/lib/active_support/ordered_hash.rb +3 -3
  171. data/lib/active_support/ordered_options.rb +6 -4
  172. data/lib/active_support/per_thread_registry.rb +5 -5
  173. data/lib/active_support/rails.rb +12 -6
  174. data/lib/active_support/railtie.rb +3 -3
  175. data/lib/active_support/reloader.rb +1 -1
  176. data/lib/active_support/rescuable.rb +6 -6
  177. data/lib/active_support/security_utils.rb +1 -1
  178. data/lib/active_support/string_inquirer.rb +8 -2
  179. data/lib/active_support/subscriber.rb +9 -5
  180. data/lib/active_support/tagged_logging.rb +4 -4
  181. data/lib/active_support/test_case.rb +12 -29
  182. data/lib/active_support/testing/assertions.rb +100 -2
  183. data/lib/active_support/testing/autorun.rb +2 -2
  184. data/lib/active_support/testing/constant_lookup.rb +0 -1
  185. data/lib/active_support/testing/declarative.rb +1 -1
  186. data/lib/active_support/testing/deprecation.rb +3 -2
  187. data/lib/active_support/testing/isolation.rb +15 -22
  188. data/lib/active_support/testing/method_call_assertions.rb +1 -1
  189. data/lib/active_support/testing/setup_and_teardown.rb +2 -2
  190. data/lib/active_support/testing/stream.rb +28 -28
  191. data/lib/active_support/testing/tagged_logging.rb +1 -1
  192. data/lib/active_support/testing/time_helpers.rb +45 -11
  193. data/lib/active_support/time.rb +12 -12
  194. data/lib/active_support/time_with_zone.rb +16 -14
  195. data/lib/active_support/values/time_zone.rb +100 -31
  196. data/lib/active_support/values/unicode_tables.dat +0 -0
  197. data/lib/active_support/version.rb +1 -1
  198. data/lib/active_support/xml_mini.rb +34 -36
  199. data/lib/active_support/xml_mini/jdom.rb +112 -112
  200. data/lib/active_support/xml_mini/libxml.rb +12 -11
  201. data/lib/active_support/xml_mini/libxmlsax.rb +13 -14
  202. data/lib/active_support/xml_mini/nokogiri.rb +10 -10
  203. data/lib/active_support/xml_mini/nokogirisax.rb +12 -13
  204. data/lib/active_support/xml_mini/rexml.rb +9 -9
  205. metadata +8 -9
  206. data/lib/active_support/concurrency/latch.rb +0 -26
  207. data/lib/active_support/core_ext/kernel/debugger.rb +0 -3
  208. data/lib/active_support/core_ext/module/method_transplanting.rb +0 -3
  209. data/lib/active_support/core_ext/module/qualified_const.rb +0 -70
  210. data/lib/active_support/core_ext/struct.rb +0 -3
  211. data/lib/active_support/core_ext/time/marshal.rb +0 -3
@@ -1,12 +1,12 @@
1
1
  class Module
2
2
  # Declares an attribute reader backed by an internally-named instance variable.
3
3
  def attr_internal_reader(*attrs)
4
- attrs.each {|attr_name| attr_internal_define(attr_name, :reader)}
4
+ attrs.each { |attr_name| attr_internal_define(attr_name, :reader) }
5
5
  end
6
6
 
7
7
  # Declares an attribute writer backed by an internally-named instance variable.
8
8
  def attr_internal_writer(*attrs)
9
- attrs.each {|attr_name| attr_internal_define(attr_name, :writer)}
9
+ attrs.each { |attr_name| attr_internal_define(attr_name, :writer) }
10
10
  end
11
11
 
12
12
  # Declares an attribute reader and writer backed by an internally-named instance
@@ -18,7 +18,7 @@ class Module
18
18
  alias_method :attr_internal, :attr_internal_accessor
19
19
 
20
20
  class << self; attr_accessor :attr_internal_naming_format end
21
- self.attr_internal_naming_format = '@_%s'
21
+ self.attr_internal_naming_format = "@_%s"
22
22
 
23
23
  private
24
24
  def attr_internal_ivar_name(attr)
@@ -26,7 +26,7 @@ class Module
26
26
  end
27
27
 
28
28
  def attr_internal_define(attr_name, type)
29
- internal_name = attr_internal_ivar_name(attr_name).sub(/\A@/, '')
29
+ internal_name = attr_internal_ivar_name(attr_name).sub(/\A@/, "")
30
30
  # use native attr_* methods as they are faster on some Ruby implementations
31
31
  send("attr_#{type}", internal_name)
32
32
  attr_name, internal_name = "#{attr_name}=", "#{internal_name}=" if type == :writer
@@ -1,4 +1,5 @@
1
- require 'active_support/core_ext/array/extract_options'
1
+ require "active_support/core_ext/array/extract_options"
2
+ require "active_support/core_ext/regexp"
2
3
 
3
4
  # Extends the module object with class/module and instance accessors for
4
5
  # class/module attributes, just like the native attr* accessors for instance
@@ -6,7 +7,8 @@ require 'active_support/core_ext/array/extract_options'
6
7
  class Module
7
8
  # Defines a class attribute and creates a class and instance reader methods.
8
9
  # The underlying class variable is set to +nil+, if it is not previously
9
- # defined.
10
+ # defined. All class and instance methods created will be public, even if
11
+ # this method is called with a private or protected access modifier.
10
12
  #
11
13
  # module HairColors
12
14
  # mattr_reader :hair_colors
@@ -53,7 +55,7 @@ class Module
53
55
  def mattr_reader(*syms)
54
56
  options = syms.extract_options!
55
57
  syms.each do |sym|
56
- raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /\A[_A-Za-z]\w*\z/
58
+ raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
57
59
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
58
60
  @@#{sym} = nil unless defined? @@#{sym}
59
61
 
@@ -75,7 +77,9 @@ class Module
75
77
  alias :cattr_reader :mattr_reader
76
78
 
77
79
  # Defines a class attribute and creates a class and instance writer methods to
78
- # allow assignment to the attribute.
80
+ # allow assignment to the attribute. All class and instance methods created
81
+ # will be public, even if this method is called with a private or protected
82
+ # access modifier.
79
83
  #
80
84
  # module HairColors
81
85
  # mattr_writer :hair_colors
@@ -119,7 +123,7 @@ class Module
119
123
  def mattr_writer(*syms)
120
124
  options = syms.extract_options!
121
125
  syms.each do |sym|
122
- raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /\A[_A-Za-z]\w*\z/
126
+ raise NameError.new("invalid attribute name: #{sym}") unless /\A[_A-Za-z]\w*\z/.match?(sym)
123
127
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
124
128
  @@#{sym} = nil unless defined? @@#{sym}
125
129
 
@@ -141,6 +145,8 @@ class Module
141
145
  alias :cattr_writer :mattr_writer
142
146
 
143
147
  # Defines both class and instance accessors for class attributes.
148
+ # All class and instance methods created will be public, even if
149
+ # this method is called with a private or protected access modifier.
144
150
  #
145
151
  # module HairColors
146
152
  # mattr_accessor :hair_colors
@@ -1,9 +1,10 @@
1
- require 'active_support/core_ext/array/extract_options'
1
+ require "active_support/core_ext/array/extract_options"
2
+ require "active_support/core_ext/regexp"
2
3
 
3
4
  # Extends the module object with class/module and instance accessors for
4
5
  # class/module attributes, just like the native attr* accessors for instance
5
6
  # attributes, but does so on a per-thread basis.
6
- #
7
+ #
7
8
  # So the values are scoped within the Thread.current space under the class name
8
9
  # of the module.
9
10
  class Module
@@ -25,7 +26,7 @@ class Module
25
26
  # end
26
27
  # # => NameError: invalid attribute name: 1_Badname
27
28
  #
28
- # If you want to opt out the creation on the instance reader method, pass
29
+ # If you want to opt out of the creation of the instance reader method, pass
29
30
  # <tt>instance_reader: false</tt> or <tt>instance_accessor: false</tt>.
30
31
  #
31
32
  # class Current
@@ -37,17 +38,20 @@ class Module
37
38
  options = syms.extract_options!
38
39
 
39
40
  syms.each do |sym|
40
- raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
41
+ raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
42
+
43
+ # The following generated method concatenates `name` because we want it
44
+ # to work with inheritance via polymorphism.
41
45
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
42
46
  def self.#{sym}
43
- Thread.current["attr_"+ name + "_#{sym}"]
47
+ Thread.current["attr_" + name + "_#{sym}"]
44
48
  end
45
49
  EOS
46
50
 
47
51
  unless options[:instance_reader] == false || options[:instance_accessor] == false
48
52
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
49
53
  def #{sym}
50
- Thread.current["attr_"+ self.class.name + "_#{sym}"]
54
+ self.class.#{sym}
51
55
  end
52
56
  EOS
53
57
  end
@@ -65,7 +69,7 @@ class Module
65
69
  # Current.user = "DHH"
66
70
  # Thread.current[:attr_Current_user] # => "DHH"
67
71
  #
68
- # If you want to opt out the instance writer method, pass
72
+ # If you want to opt out of the creation of the instance writer method, pass
69
73
  # <tt>instance_writer: false</tt> or <tt>instance_accessor: false</tt>.
70
74
  #
71
75
  # class Current
@@ -76,17 +80,20 @@ class Module
76
80
  def thread_mattr_writer(*syms) # :nodoc:
77
81
  options = syms.extract_options!
78
82
  syms.each do |sym|
79
- raise NameError.new("invalid attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
83
+ raise NameError.new("invalid attribute name: #{sym}") unless /^[_A-Za-z]\w*$/.match?(sym)
84
+
85
+ # The following generated method concatenates `name` because we want it
86
+ # to work with inheritance via polymorphism.
80
87
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
81
88
  def self.#{sym}=(obj)
82
- Thread.current["attr_"+ name + "_#{sym}"] = obj
89
+ Thread.current["attr_" + name + "_#{sym}"] = obj
83
90
  end
84
91
  EOS
85
92
 
86
93
  unless options[:instance_writer] == false || options[:instance_accessor] == false
87
94
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
88
95
  def #{sym}=(obj)
89
- Thread.current["attr_"+ self.class.name + "_#{sym}"] = obj
96
+ self.class.#{sym} = obj
90
97
  end
91
98
  EOS
92
99
  end
@@ -133,9 +140,9 @@ class Module
133
140
  #
134
141
  # Current.new.user = "DHH" # => NoMethodError
135
142
  # Current.new.user # => NoMethodError
136
- def thread_mattr_accessor(*syms, &blk)
137
- thread_mattr_reader(*syms, &blk)
138
- thread_mattr_writer(*syms, &blk)
143
+ def thread_mattr_accessor(*syms)
144
+ thread_mattr_reader(*syms)
145
+ thread_mattr_writer(*syms)
139
146
  end
140
147
  alias :thread_cattr_accessor :thread_mattr_accessor
141
148
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/concern'
1
+ require "active_support/concern"
2
2
 
3
3
  class Module
4
4
  # = Bite-sized separation of concerns
@@ -1,4 +1,5 @@
1
- require 'set'
1
+ require "set"
2
+ require "active_support/core_ext/regexp"
2
3
 
3
4
  class Module
4
5
  # Error generated by +delegate+ when a method is called on +nil+ and +allow_nil+
@@ -19,7 +20,8 @@ class Module
19
20
  # ==== Options
20
21
  # * <tt>:to</tt> - Specifies the target object
21
22
  # * <tt>:prefix</tt> - Prefixes the new method with the target name or a custom prefix
22
- # * <tt>:allow_nil</tt> - if set to true, prevents a +NoMethodError+ from being raised
23
+ # * <tt>:allow_nil</tt> - if set to true, prevents a +Module::DelegationError+
24
+ # from being raised
23
25
  #
24
26
  # The macro receives one or more method names (specified as symbols or
25
27
  # strings) and the name of the target object via the <tt>:to</tt> option
@@ -111,18 +113,19 @@ class Module
111
113
  # invoice.customer_address # => 'Vimmersvej 13'
112
114
  #
113
115
  # If the target is +nil+ and does not respond to the delegated method a
114
- # +NoMethodError+ is raised, as with any other value. Sometimes, however, it
115
- # makes sense to be robust to that situation and that is the purpose of the
116
- # <tt>:allow_nil</tt> option: If the target is not +nil+, or it is and
117
- # responds to the method, everything works as usual. But if it is +nil+ and
118
- # does not respond to the delegated method, +nil+ is returned.
116
+ # +Module::DelegationError+ is raised, as with any other value. Sometimes,
117
+ # however, it makes sense to be robust to that situation and that is the
118
+ # purpose of the <tt>:allow_nil</tt> option: If the target is not +nil+, or it
119
+ # is and responds to the method, everything works as usual. But if it is +nil+
120
+ # and does not respond to the delegated method, +nil+ is returned.
119
121
  #
120
122
  # class User < ActiveRecord::Base
121
123
  # has_one :profile
122
124
  # delegate :age, to: :profile
123
125
  # end
124
126
  #
125
- # User.new.age # raises NoMethodError: undefined method `age'
127
+ # User.new.age
128
+ # # => Module::DelegationError: User#age delegated to profile.age, but profile is nil
126
129
  #
127
130
  # But if not having a profile yet is fine and should not be an error
128
131
  # condition:
@@ -149,21 +152,20 @@ class Module
149
152
  # Foo.new("Bar").name # raises NoMethodError: undefined method `name'
150
153
  #
151
154
  # The target method must be public, otherwise it will raise +NoMethodError+.
152
- #
153
155
  def delegate(*methods, to: nil, prefix: nil, allow_nil: nil)
154
156
  unless to
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).'
157
+ raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter)."
156
158
  end
157
159
 
158
- if prefix == true && to =~ /^[^a-z_]/
159
- raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
160
+ if prefix == true && /^[^a-z_]/.match?(to)
161
+ raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
160
162
  end
161
163
 
162
164
  method_prefix = \
163
165
  if prefix
164
166
  "#{prefix == true ? to : prefix}_"
165
167
  else
166
- ''
168
+ ""
167
169
  end
168
170
 
169
171
  location = caller_locations(1, 1).first
@@ -175,7 +177,7 @@ class Module
175
177
  methods.each do |method|
176
178
  # Attribute writer methods only accept one argument. Makes sure []=
177
179
  # methods still accept two arguments.
178
- definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block'
180
+ definition = /[^\]]=$/.match?(method) ? "arg" : "*args, &block"
179
181
 
180
182
  # The following generated method calls the target exactly once, storing
181
183
  # the returned value in a dummy variable.
@@ -192,7 +194,7 @@ class Module
192
194
  " _.#{method}(#{definition})",
193
195
  "end",
194
196
  "end"
195
- ].join ';'
197
+ ].join ";"
196
198
  else
197
199
  exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
198
200
 
@@ -207,10 +209,77 @@ class Module
207
209
  " raise",
208
210
  " end",
209
211
  "end"
210
- ].join ';'
212
+ ].join ";"
211
213
  end
212
214
 
213
215
  module_eval(method_def, file, line)
214
216
  end
215
217
  end
218
+
219
+ # When building decorators, a common pattern may emerge:
220
+ #
221
+ # class Partition
222
+ # def initialize(first_event)
223
+ # @events = [ first_event ]
224
+ # end
225
+ #
226
+ # def people
227
+ # if @events.first.detail.people.any?
228
+ # @events.collect { |e| Array(e.detail.people) }.flatten.uniq
229
+ # else
230
+ # @events.collect(&:creator).uniq
231
+ # end
232
+ # end
233
+ #
234
+ # private
235
+ # def respond_to_missing?(name, include_private = false)
236
+ # @events.respond_to?(name, include_private)
237
+ # end
238
+ #
239
+ # def method_missing(method, *args, &block)
240
+ # @events.send(method, *args, &block)
241
+ # end
242
+ # end
243
+ #
244
+ # With `Module#delegate_missing_to`, the above is condensed to:
245
+ #
246
+ # class Partition
247
+ # delegate_missing_to :@events
248
+ #
249
+ # def initialize(first_event)
250
+ # @events = [ first_event ]
251
+ # end
252
+ #
253
+ # def people
254
+ # if @events.first.detail.people.any?
255
+ # @events.collect { |e| Array(e.detail.people) }.flatten.uniq
256
+ # else
257
+ # @events.collect(&:creator).uniq
258
+ # end
259
+ # end
260
+ # end
261
+ #
262
+ # The target can be anything callable within the object. E.g. instance
263
+ # variables, methods, constants and the likes.
264
+ def delegate_missing_to(target)
265
+ target = target.to_s
266
+ target = "self.#{target}" if DELEGATION_RESERVED_METHOD_NAMES.include?(target)
267
+
268
+ module_eval <<-RUBY, __FILE__, __LINE__ + 1
269
+ def respond_to_missing?(name, include_private = false)
270
+ # It may look like an oversight, but we deliberately do not pass
271
+ # +include_private+, because they do not get delegated.
272
+
273
+ #{target}.respond_to?(name) || super
274
+ end
275
+
276
+ def method_missing(method, *args, &block)
277
+ if #{target}.respond_to?(method)
278
+ #{target}.public_send(method, *args, &block)
279
+ else
280
+ super
281
+ end
282
+ end
283
+ RUBY
284
+ end
216
285
  end
@@ -1,4 +1,4 @@
1
- require 'active_support/inflector'
1
+ require "active_support/inflector"
2
2
 
3
3
  class Module
4
4
  # Returns the name of the module containing this one.
@@ -48,21 +48,13 @@ class Module
48
48
  def parents
49
49
  parents = []
50
50
  if parent_name
51
- parts = parent_name.split('::')
51
+ parts = parent_name.split("::")
52
52
  until parts.empty?
53
- parents << ActiveSupport::Inflector.constantize(parts * '::')
53
+ parents << ActiveSupport::Inflector.constantize(parts * "::")
54
54
  parts.pop
55
55
  end
56
56
  end
57
57
  parents << Object unless parents.include? Object
58
58
  parents
59
59
  end
60
-
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
66
- constants(false)
67
- end
68
60
  end
@@ -1,5 +1,5 @@
1
- require 'active_support/core_ext/module/anonymous'
2
- require 'active_support/core_ext/string/inflections'
1
+ require "active_support/core_ext/module/anonymous"
2
+ require "active_support/core_ext/string/inflections"
3
3
 
4
4
  class Module
5
5
  def reachable? #:nodoc:
@@ -1,4 +1,4 @@
1
- require 'active_support/core_ext/numeric/bytes'
2
- require 'active_support/core_ext/numeric/time'
3
- require 'active_support/core_ext/numeric/inquiry'
4
- require 'active_support/core_ext/numeric/conversions'
1
+ require "active_support/core_ext/numeric/bytes"
2
+ require "active_support/core_ext/numeric/time"
3
+ require "active_support/core_ext/numeric/inquiry"
4
+ require "active_support/core_ext/numeric/conversions"
@@ -1,9 +1,8 @@
1
- require 'active_support/core_ext/big_decimal/conversions'
2
- require 'active_support/number_helper'
3
- require 'active_support/core_ext/module/deprecation'
1
+ require "active_support/core_ext/big_decimal/conversions"
2
+ require "active_support/number_helper"
3
+ require "active_support/core_ext/module/deprecation"
4
4
 
5
5
  module ActiveSupport::NumericWithFormat
6
-
7
6
  # Provides options for converting numbers into formatted strings.
8
7
  # Options are provided for phone numbers, currency, percentage,
9
8
  # precision, positional notation, file size and pretty printing.
@@ -126,11 +125,6 @@ module ActiveSupport::NumericWithFormat
126
125
  super(format)
127
126
  end
128
127
  end
129
-
130
- def to_formatted_s(*args)
131
- to_s(*args)
132
- end
133
- deprecate to_formatted_s: :to_s
134
128
  end
135
129
 
136
130
  # Ruby 2.4+ unifies Fixnum & Bignum into Integer.
@@ -1,26 +1,26 @@
1
1
  unless 1.respond_to?(:positive?) # TODO: Remove this file when we drop support to ruby < 2.3
2
- class Numeric
3
- # Returns true if the number is positive.
4
- #
5
- # 1.positive? # => true
6
- # 0.positive? # => false
7
- # -1.positive? # => false
8
- def positive?
9
- self > 0
10
- end
2
+ class Numeric
3
+ # Returns true if the number is positive.
4
+ #
5
+ # 1.positive? # => true
6
+ # 0.positive? # => false
7
+ # -1.positive? # => false
8
+ def positive?
9
+ self > 0
10
+ end
11
11
 
12
- # Returns true if the number is negative.
13
- #
14
- # -1.negative? # => true
15
- # 0.negative? # => false
16
- # 1.negative? # => false
17
- def negative?
18
- self < 0
12
+ # Returns true if the number is negative.
13
+ #
14
+ # -1.negative? # => true
15
+ # 0.negative? # => false
16
+ # 1.negative? # => false
17
+ def negative?
18
+ self < 0
19
+ end
19
20
  end
20
- end
21
21
 
22
- class Complex
23
- undef :positive?
24
- undef :negative?
25
- end
22
+ class Complex
23
+ undef :positive?
24
+ undef :negative?
25
+ end
26
26
  end