activesupport 3.1.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

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