activesupport 3.2.22.5 → 4.0.0.beta1

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 (214) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +325 -136
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -2
  5. data/lib/active_support.rb +8 -21
  6. data/lib/active_support/backtrace_cleaner.rb +33 -25
  7. data/lib/active_support/basic_object.rb +7 -17
  8. data/lib/active_support/benchmarkable.rb +19 -15
  9. data/lib/active_support/buffered_logger.rb +9 -113
  10. data/lib/active_support/cache.rb +203 -171
  11. data/lib/active_support/cache/file_store.rb +12 -12
  12. data/lib/active_support/cache/mem_cache_store.rb +24 -30
  13. data/lib/active_support/cache/memory_store.rb +2 -0
  14. data/lib/active_support/callbacks.rb +195 -247
  15. data/lib/active_support/concern.rb +16 -23
  16. data/lib/active_support/concurrency/latch.rb +27 -0
  17. data/lib/active_support/configurable.rb +69 -12
  18. data/lib/active_support/core_ext.rb +1 -0
  19. data/lib/active_support/core_ext/array.rb +0 -1
  20. data/lib/active_support/core_ext/array/access.rb +17 -9
  21. data/lib/active_support/core_ext/array/conversions.rb +113 -55
  22. data/lib/active_support/core_ext/array/extract_options.rb +2 -2
  23. data/lib/active_support/core_ext/array/grouping.rb +21 -22
  24. data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
  25. data/lib/active_support/core_ext/array/wrap.rb +11 -14
  26. data/lib/active_support/core_ext/big_decimal/conversions.rb +7 -24
  27. data/lib/active_support/core_ext/class/attribute.rb +12 -8
  28. data/lib/active_support/core_ext/class/attribute_accessors.rb +14 -12
  29. data/lib/active_support/core_ext/class/delegating_attributes.rb +15 -19
  30. data/lib/active_support/core_ext/class/subclasses.rb +11 -5
  31. data/lib/active_support/core_ext/date.rb +6 -0
  32. data/lib/active_support/core_ext/date/calculations.rb +34 -188
  33. data/lib/active_support/core_ext/date/conversions.rb +16 -38
  34. data/lib/active_support/core_ext/date/infinite_comparable.rb +5 -0
  35. data/lib/active_support/core_ext/date/zones.rb +25 -2
  36. data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
  37. data/lib/active_support/core_ext/date_time.rb +5 -0
  38. data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
  39. data/lib/active_support/core_ext/date_time/calculations.rb +73 -65
  40. data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
  41. data/lib/active_support/core_ext/date_time/infinite_comparable.rb +5 -0
  42. data/lib/active_support/core_ext/date_time/zones.rb +11 -8
  43. data/lib/active_support/core_ext/enumerable.rb +26 -73
  44. data/lib/active_support/core_ext/file.rb +0 -1
  45. data/lib/active_support/core_ext/file/atomic.rb +27 -11
  46. data/lib/active_support/core_ext/hash.rb +0 -1
  47. data/lib/active_support/core_ext/hash/conversions.rb +145 -79
  48. data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
  49. data/lib/active_support/core_ext/hash/diff.rb +5 -4
  50. data/lib/active_support/core_ext/hash/except.rb +1 -9
  51. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
  52. data/lib/active_support/core_ext/hash/keys.rb +108 -24
  53. data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
  54. data/lib/active_support/core_ext/hash/slice.rb +12 -12
  55. data/lib/active_support/core_ext/infinite_comparable.rb +35 -0
  56. data/lib/active_support/core_ext/integer/inflections.rb +13 -1
  57. data/lib/active_support/core_ext/integer/time.rb +17 -12
  58. data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
  59. data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
  60. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
  61. data/lib/active_support/core_ext/load_error.rb +7 -5
  62. data/lib/active_support/core_ext/logger.rb +7 -23
  63. data/lib/active_support/core_ext/marshal.rb +19 -0
  64. data/lib/active_support/core_ext/module.rb +1 -3
  65. data/lib/active_support/core_ext/module/aliasing.rb +8 -9
  66. data/lib/active_support/core_ext/module/anonymous.rb +2 -7
  67. data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
  68. data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
  69. data/lib/active_support/core_ext/module/delegation.rb +57 -40
  70. data/lib/active_support/core_ext/module/deprecation.rb +19 -3
  71. data/lib/active_support/core_ext/module/introspection.rb +17 -27
  72. data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
  73. data/lib/active_support/core_ext/module/remove_method.rb +1 -5
  74. data/lib/active_support/core_ext/numeric.rb +2 -0
  75. data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
  76. data/lib/active_support/core_ext/numeric/infinite_comparable.rb +9 -0
  77. data/lib/active_support/core_ext/numeric/time.rb +6 -6
  78. data/lib/active_support/core_ext/object.rb +1 -0
  79. data/lib/active_support/core_ext/object/acts_like.rb +4 -4
  80. data/lib/active_support/core_ext/object/blank.rb +7 -23
  81. data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
  82. data/lib/active_support/core_ext/object/duplicable.rb +1 -30
  83. data/lib/active_support/core_ext/object/inclusion.rb +6 -6
  84. data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
  85. data/lib/active_support/core_ext/object/to_json.rb +8 -0
  86. data/lib/active_support/core_ext/object/to_param.rb +5 -2
  87. data/lib/active_support/core_ext/object/try.rb +46 -25
  88. data/lib/active_support/core_ext/object/with_options.rb +7 -8
  89. data/lib/active_support/core_ext/proc.rb +3 -0
  90. data/lib/active_support/core_ext/range.rb +0 -2
  91. data/lib/active_support/core_ext/range/conversions.rb +0 -2
  92. data/lib/active_support/core_ext/range/include_range.rb +1 -1
  93. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  94. data/lib/active_support/core_ext/string.rb +2 -2
  95. data/lib/active_support/core_ext/string/access.rb +95 -90
  96. data/lib/active_support/core_ext/string/conversions.rb +29 -38
  97. data/lib/active_support/core_ext/string/encoding.rb +6 -9
  98. data/lib/active_support/core_ext/string/filters.rb +24 -18
  99. data/lib/active_support/core_ext/string/indent.rb +43 -0
  100. data/lib/active_support/core_ext/string/inflections.rb +70 -60
  101. data/lib/active_support/core_ext/string/inquiry.rb +2 -2
  102. data/lib/active_support/core_ext/string/multibyte.rb +41 -64
  103. data/lib/active_support/core_ext/string/output_safety.rb +59 -51
  104. data/lib/active_support/core_ext/string/zones.rb +13 -0
  105. data/lib/active_support/core_ext/struct.rb +6 -0
  106. data/lib/active_support/core_ext/thread.rb +74 -0
  107. data/lib/active_support/core_ext/time.rb +6 -0
  108. data/lib/active_support/core_ext/time/calculations.rb +105 -193
  109. data/lib/active_support/core_ext/time/conversions.rb +27 -51
  110. data/lib/active_support/core_ext/time/infinite_comparable.rb +5 -0
  111. data/lib/active_support/core_ext/time/marshal.rb +0 -27
  112. data/lib/active_support/core_ext/time/zones.rb +27 -17
  113. data/lib/active_support/core_ext/uri.rb +13 -17
  114. data/lib/active_support/dependencies.rb +160 -141
  115. data/lib/active_support/dependencies/autoload.rb +47 -20
  116. data/lib/active_support/deprecation.rb +39 -14
  117. data/lib/active_support/deprecation/behaviors.rb +44 -30
  118. data/lib/active_support/deprecation/instance_delegator.rb +24 -0
  119. data/lib/active_support/deprecation/method_wrappers.rb +33 -18
  120. data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
  121. data/lib/active_support/deprecation/reporting.rb +40 -11
  122. data/lib/active_support/descendants_tracker.rb +34 -19
  123. data/lib/active_support/duration.rb +6 -8
  124. data/lib/active_support/file_update_checker.rb +63 -47
  125. data/lib/active_support/gzip.rb +11 -5
  126. data/lib/active_support/hash_with_indifferent_access.rb +112 -37
  127. data/lib/active_support/i18n.rb +4 -0
  128. data/lib/active_support/i18n_railtie.rb +5 -22
  129. data/lib/active_support/inflections.rb +14 -12
  130. data/lib/active_support/inflector/inflections.rb +108 -71
  131. data/lib/active_support/inflector/methods.rb +181 -160
  132. data/lib/active_support/inflector/transliterate.rb +16 -17
  133. data/lib/active_support/json/decoding.rb +18 -17
  134. data/lib/active_support/json/encoding.rb +93 -39
  135. data/lib/active_support/json/variable.rb +10 -1
  136. data/lib/active_support/key_generator.rb +75 -0
  137. data/lib/active_support/lazy_load_hooks.rb +21 -19
  138. data/lib/active_support/locale/en.yml +100 -3
  139. data/lib/active_support/log_subscriber.rb +56 -36
  140. data/lib/active_support/log_subscriber/test_helper.rb +18 -15
  141. data/lib/active_support/logger.rb +57 -0
  142. data/lib/active_support/logger_silence.rb +24 -0
  143. data/lib/active_support/message_encryptor.rb +32 -29
  144. data/lib/active_support/message_verifier.rb +8 -14
  145. data/lib/active_support/multibyte.rb +5 -28
  146. data/lib/active_support/multibyte/chars.rb +80 -333
  147. data/lib/active_support/multibyte/unicode.rb +74 -64
  148. data/lib/active_support/notifications.rb +57 -25
  149. data/lib/active_support/notifications/fanout.rb +105 -18
  150. data/lib/active_support/notifications/instrumenter.rb +32 -13
  151. data/lib/active_support/number_helper.rb +636 -0
  152. data/lib/active_support/ordered_hash.rb +8 -190
  153. data/lib/active_support/ordered_options.rb +21 -23
  154. data/lib/active_support/proxy_object.rb +13 -0
  155. data/lib/active_support/rails.rb +27 -0
  156. data/lib/active_support/railtie.rb +12 -32
  157. data/lib/active_support/rescuable.rb +9 -4
  158. data/lib/active_support/string_inquirer.rb +13 -8
  159. data/lib/active_support/tagged_logging.rb +51 -73
  160. data/lib/active_support/test_case.rb +46 -17
  161. data/lib/active_support/testing/assertions.rb +56 -26
  162. data/lib/active_support/testing/autorun.rb +5 -0
  163. data/lib/active_support/testing/constant_lookup.rb +52 -0
  164. data/lib/active_support/testing/declarative.rb +1 -1
  165. data/lib/active_support/testing/deprecation.rb +0 -19
  166. data/lib/active_support/testing/isolation.rb +25 -58
  167. data/lib/active_support/testing/pending.rb +5 -43
  168. data/lib/active_support/testing/setup_and_teardown.rb +6 -92
  169. data/lib/active_support/testing/tagged_logging.rb +25 -0
  170. data/lib/active_support/time.rb +6 -21
  171. data/lib/active_support/time_with_zone.rb +78 -43
  172. data/lib/active_support/values/time_zone.rb +77 -58
  173. data/lib/active_support/values/unicode_tables.dat +0 -0
  174. data/lib/active_support/version.rb +4 -4
  175. data/lib/active_support/xml_mini.rb +35 -17
  176. data/lib/active_support/xml_mini/jdom.rb +9 -17
  177. data/lib/active_support/xml_mini/libxml.rb +1 -2
  178. data/lib/active_support/xml_mini/libxmlsax.rb +1 -2
  179. data/lib/active_support/xml_mini/nokogiri.rb +1 -2
  180. data/lib/active_support/xml_mini/nokogirisax.rb +1 -2
  181. data/lib/active_support/xml_mini/rexml.rb +6 -8
  182. metadata +107 -77
  183. data/lib/active_support/base64.rb +0 -54
  184. data/lib/active_support/core_ext/array/random_access.rb +0 -30
  185. data/lib/active_support/core_ext/date/freeze.rb +0 -33
  186. data/lib/active_support/core_ext/exception.rb +0 -3
  187. data/lib/active_support/core_ext/file/path.rb +0 -5
  188. data/lib/active_support/core_ext/float.rb +0 -1
  189. data/lib/active_support/core_ext/float/rounding.rb +0 -19
  190. data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
  191. data/lib/active_support/core_ext/io.rb +0 -15
  192. data/lib/active_support/core_ext/module/method_names.rb +0 -14
  193. data/lib/active_support/core_ext/module/synchronization.rb +0 -45
  194. data/lib/active_support/core_ext/process.rb +0 -1
  195. data/lib/active_support/core_ext/process/daemon.rb +0 -23
  196. data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
  197. data/lib/active_support/core_ext/range/cover.rb +0 -3
  198. data/lib/active_support/core_ext/rexml.rb +0 -46
  199. data/lib/active_support/core_ext/string/interpolation.rb +0 -2
  200. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
  201. data/lib/active_support/memoizable.rb +0 -116
  202. data/lib/active_support/multibyte/exceptions.rb +0 -8
  203. data/lib/active_support/multibyte/utils.rb +0 -60
  204. data/lib/active_support/ruby/shim.rb +0 -22
  205. data/lib/active_support/security_utils.rb +0 -27
  206. data/lib/active_support/testing/mochaing.rb +0 -7
  207. data/lib/active_support/testing/performance.rb +0 -317
  208. data/lib/active_support/testing/performance/jruby.rb +0 -115
  209. data/lib/active_support/testing/performance/rubinius.rb +0 -113
  210. data/lib/active_support/testing/performance/ruby.rb +0 -152
  211. data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
  212. data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
  213. data/lib/active_support/time/autoload.rb +0 -5
  214. data/lib/active_support/whiny_nil.rb +0 -24
@@ -1,8 +1,9 @@
1
1
  require 'rbconfig'
2
- require 'stringio'
2
+ require 'tempfile'
3
3
 
4
4
  module Kernel
5
- # Sets $VERBOSE to nil for the duration of the block and back to its original value afterwards.
5
+ # Sets $VERBOSE to nil for the duration of the block and back to its original
6
+ # value afterwards.
6
7
  #
7
8
  # silence_warnings do
8
9
  # value = noisy_call # no warning voiced
@@ -13,12 +14,14 @@ module Kernel
13
14
  with_warnings(nil) { yield }
14
15
  end
15
16
 
16
- # Sets $VERBOSE to true for the duration of the block and back to its original value afterwards.
17
+ # Sets $VERBOSE to +true+ for the duration of the block and back to its
18
+ # original value afterwards.
17
19
  def enable_warnings
18
20
  with_warnings(true) { yield }
19
21
  end
20
22
 
21
- # Sets $VERBOSE for the duration of the block and back to its original value afterwards.
23
+ # Sets $VERBOSE for the duration of the block and back to its original
24
+ # value afterwards.
22
25
  def with_warnings(flag)
23
26
  old_verbose, $VERBOSE = $VERBOSE, flag
24
27
  yield
@@ -51,40 +54,51 @@ module Kernel
51
54
  #
52
55
  # suppress(ZeroDivisionError) do
53
56
  # 1/0
54
- # puts "This code is NOT reached"
57
+ # puts 'This code is NOT reached'
55
58
  # end
56
59
  #
57
- # puts "This code gets executed and nothing related to ZeroDivisionError was seen"
60
+ # puts 'This code gets executed and nothing related to ZeroDivisionError was seen'
58
61
  def suppress(*exception_classes)
59
- begin yield
60
- rescue Exception => e
61
- raise unless exception_classes.any? { |cls| e.kind_of?(cls) }
62
- end
62
+ yield
63
+ rescue Exception => e
64
+ raise unless exception_classes.any? { |cls| e.kind_of?(cls) }
63
65
  end
64
66
 
65
67
  # Captures the given stream and returns it:
66
68
  #
67
- # stream = capture(:stdout) { puts "Cool" }
68
- # stream # => "Cool\n"
69
+ # stream = capture(:stdout) { puts 'notice' }
70
+ # stream # => "notice\n"
71
+ #
72
+ # stream = capture(:stderr) { warn 'error' }
73
+ # stream # => "error\n"
74
+ #
75
+ # even for subprocesses:
76
+ #
77
+ # stream = capture(:stdout) { system('echo notice') }
78
+ # stream # => "notice\n"
69
79
  #
80
+ # stream = capture(:stderr) { system('echo error 1>&2') }
81
+ # stream # => "error\n"
70
82
  def capture(stream)
71
- begin
72
- stream = stream.to_s
73
- eval "$#{stream} = StringIO.new"
74
- yield
75
- result = eval("$#{stream}").string
76
- ensure
77
- eval("$#{stream} = #{stream.upcase}")
78
- end
83
+ stream = stream.to_s
84
+ captured_stream = Tempfile.new(stream)
85
+ stream_io = eval("$#{stream}")
86
+ origin_stream = stream_io.dup
87
+ stream_io.reopen(captured_stream)
88
+
89
+ yield
79
90
 
80
- result
91
+ stream_io.rewind
92
+ return captured_stream.read
93
+ ensure
94
+ captured_stream.unlink
95
+ stream_io.reopen(origin_stream)
81
96
  end
82
97
  alias :silence :capture
83
98
 
84
99
  # Silences both STDOUT and STDERR, even for subprocesses.
85
100
  #
86
101
  # quietly { system 'bundle install' }
87
- #
88
102
  def quietly
89
103
  silence_stream(STDOUT) do
90
104
  silence_stream(STDERR) do
@@ -1,11 +1,4 @@
1
1
  module Kernel
2
- # Returns the object's singleton class.
3
- def singleton_class
4
- class << self
5
- self
6
- end
7
- end unless respond_to?(:singleton_class) # exists in 1.9.2
8
-
9
2
  # class_eval on an object acts like singleton_class.class_eval.
10
3
  def class_eval(*args, &block)
11
4
  singleton_class.class_eval(*args, &block)
@@ -6,12 +6,14 @@ class LoadError
6
6
  /^cannot load such file -- (.+)$/i,
7
7
  ]
8
8
 
9
- def path
10
- @path ||= begin
11
- REGEXPS.find do |regex|
12
- message =~ regex
9
+ unless method_defined?(:path)
10
+ def path
11
+ @path ||= begin
12
+ REGEXPS.find do |regex|
13
+ message =~ regex
14
+ end
15
+ $1
13
16
  end
14
- $1
15
17
  end
16
18
  end
17
19
 
@@ -1,5 +1,8 @@
1
1
  require 'active_support/core_ext/class/attribute_accessors'
2
2
  require 'active_support/deprecation'
3
+ require 'active_support/logger_silence'
4
+
5
+ ActiveSupport::Deprecation.warn 'this file is deprecated and will be removed'
3
6
 
4
7
  # Adds the 'around_level' method to Logger.
5
8
  class Logger #:nodoc:
@@ -29,34 +32,15 @@ require 'logger'
29
32
  #
30
33
  # logger.datetime_format = "%Y-%m-%d"
31
34
  #
32
- # Note: This logger is deprecated in favor of ActiveSupport::BufferedLogger
35
+ # Note: This logger is deprecated in favor of ActiveSupport::Logger
33
36
  class Logger
34
- ##
35
- # :singleton-method:
36
- # Set to false to disable the silencer
37
- cattr_accessor :silencer
38
- self.silencer = true
39
-
40
- # Silences the logger for the duration of the block.
41
- def silence(temporary_level = Logger::ERROR)
42
- if silencer
43
- begin
44
- old_logger_level, self.level = level, temporary_level
45
- yield self
46
- ensure
47
- self.level = old_logger_level
48
- end
49
- else
50
- yield self
51
- end
52
- end
53
- deprecate :silence
37
+ include LoggerSilence
54
38
 
55
39
  alias :old_datetime_format= :datetime_format=
56
40
  # Logging date-time format (string passed to +strftime+). Ignored if the formatter
57
41
  # does not respond to datetime_format=.
58
- def datetime_format=(datetime_format)
59
- formatter.datetime_format = datetime_format if formatter.respond_to?(:datetime_format=)
42
+ def datetime_format=(format)
43
+ formatter.datetime_format = format if formatter.respond_to?(:datetime_format=)
60
44
  end
61
45
 
62
46
  alias :old_datetime_format :datetime_format
@@ -0,0 +1,19 @@
1
+ module Marshal
2
+ class << self
3
+ def load_with_autoloading(source)
4
+ load_without_autoloading(source)
5
+ rescue ArgumentError, NameError => exc
6
+ if exc.message.match(%r|undefined class/module (.+)|)
7
+ # try loading the class/module
8
+ $1.constantize
9
+ # if it is a IO we need to go back to read the object
10
+ source.rewind if source.respond_to?(:rewind)
11
+ retry
12
+ else
13
+ raise exc
14
+ end
15
+ end
16
+
17
+ alias_method_chain :load, :autoloading
18
+ end
19
+ end
@@ -5,8 +5,6 @@ require 'active_support/core_ext/module/reachable'
5
5
  require 'active_support/core_ext/module/attribute_accessors'
6
6
  require 'active_support/core_ext/module/attr_internal'
7
7
  require 'active_support/core_ext/module/delegation'
8
- require 'active_support/core_ext/module/synchronization'
9
8
  require 'active_support/core_ext/module/deprecation'
10
9
  require 'active_support/core_ext/module/remove_method'
11
- require 'active_support/core_ext/module/method_names'
12
- require 'active_support/core_ext/module/qualified_const'
10
+ require 'active_support/core_ext/module/qualified_const'
@@ -26,26 +26,25 @@ class Module
26
26
  aliased_target, punctuation = target.to_s.sub(/([?!=])$/, ''), $1
27
27
  yield(aliased_target, punctuation) if block_given?
28
28
 
29
- with_method, without_method = "#{aliased_target}_with_#{feature}#{punctuation}", "#{aliased_target}_without_#{feature}#{punctuation}"
29
+ with_method = "#{aliased_target}_with_#{feature}#{punctuation}"
30
+ without_method = "#{aliased_target}_without_#{feature}#{punctuation}"
30
31
 
31
32
  alias_method without_method, target
32
33
  alias_method target, with_method
33
34
 
34
35
  case
35
- when public_method_defined?(without_method)
36
- public target
37
- when protected_method_defined?(without_method)
38
- protected target
39
- when private_method_defined?(without_method)
40
- private target
36
+ when public_method_defined?(without_method)
37
+ public target
38
+ when protected_method_defined?(without_method)
39
+ protected target
40
+ when private_method_defined?(without_method)
41
+ private target
41
42
  end
42
43
  end
43
44
 
44
45
  # Allows you to make aliases for attributes, which includes
45
46
  # getter, setter, and query methods.
46
47
  #
47
- # Example:
48
- #
49
48
  # class Content < ActiveRecord::Base
50
49
  # # has a title attribute
51
50
  # end
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/object/blank'
2
-
3
1
  class Module
4
2
  # A module may or may not have a name.
5
3
  #
@@ -7,7 +5,7 @@ class Module
7
5
  # M.name # => "M"
8
6
  #
9
7
  # m = Module.new
10
- # m.name # => ""
8
+ # m.name # => nil
11
9
  #
12
10
  # A module gets a name when it is first assigned to a constant. Either
13
11
  # via the +module+ or +class+ keyword or by an explicit assignment:
@@ -15,10 +13,7 @@ class Module
15
13
  # m = Module.new # creates an anonymous module
16
14
  # M = m # => m gets a name here as a side-effect
17
15
  # m.name # => "M"
18
- #
19
16
  def anonymous?
20
- # Uses blank? because the name of an anonymous class is an empty
21
- # string in 1.8, and nil in 1.9.
22
- name.blank?
17
+ name.nil?
23
18
  end
24
19
  end
@@ -15,7 +15,6 @@ class Module
15
15
  attr_internal_reader(*attrs)
16
16
  attr_internal_writer(*attrs)
17
17
  end
18
-
19
18
  alias_method :attr_internal, :attr_internal_accessor
20
19
 
21
20
  class << self; attr_accessor :attr_internal_naming_format end
@@ -4,6 +4,7 @@ class Module
4
4
  def mattr_reader(*syms)
5
5
  options = syms.extract_options!
6
6
  syms.each do |sym|
7
+ raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
7
8
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
8
9
  @@#{sym} = nil unless defined? @@#{sym}
9
10
 
@@ -25,6 +26,7 @@ class Module
25
26
  def mattr_writer(*syms)
26
27
  options = syms.extract_options!
27
28
  syms.each do |sym|
29
+ raise NameError.new('invalid attribute name') unless sym =~ /^[_A-Za-z]\w*$/
28
30
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
29
31
  def self.#{sym}=(obj)
30
32
  @@#{sym} = obj
@@ -44,19 +46,19 @@ class Module
44
46
  # Extends the module object with module and instance accessors for class attributes,
45
47
  # just like the native attr* accessors for instance attributes.
46
48
  #
47
- # module AppConfiguration
48
- # mattr_accessor :google_api_key
49
- # self.google_api_key = "123456789"
49
+ # module AppConfiguration
50
+ # mattr_accessor :google_api_key
50
51
  #
51
- # mattr_accessor :paypal_url
52
- # self.paypal_url = "www.sandbox.paypal.com"
53
- # end
52
+ # self.google_api_key = "123456789"
53
+ # end
54
54
  #
55
- # AppConfiguration.google_api_key = "overriding the api key!"
55
+ # AppConfiguration.google_api_key # => "123456789"
56
+ # AppConfiguration.google_api_key = "overriding the api key!"
57
+ # AppConfiguration.google_api_key # => "overriding the api key!"
56
58
  #
57
- # To opt out of the instance writer method, pass :instance_writer => false.
58
- # To opt out of the instance reader method, pass :instance_reader => false.
59
- # To opt out of both instance methods, pass :instance_accessor => false.
59
+ # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
60
+ # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
61
+ # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
60
62
  def mattr_accessor(*syms)
61
63
  mattr_reader(*syms)
62
64
  mattr_writer(*syms)
@@ -1,5 +1,5 @@
1
1
  class Module
2
- # Provides a delegate class method to easily expose contained objects' methods
2
+ # Provides a delegate class method to easily expose contained objects' public methods
3
3
  # as your own. Pass one or more methods (specified as symbols or strings)
4
4
  # and the name of the target object via the <tt>:to</tt> option (also a symbol
5
5
  # or string). At least one method and the <tt>:to</tt> option are required.
@@ -8,17 +8,17 @@ class Module
8
8
  #
9
9
  # class Greeter < ActiveRecord::Base
10
10
  # def hello
11
- # "hello"
11
+ # 'hello'
12
12
  # end
13
13
  #
14
14
  # def goodbye
15
- # "goodbye"
15
+ # 'goodbye'
16
16
  # end
17
17
  # end
18
18
  #
19
19
  # class Foo < ActiveRecord::Base
20
20
  # belongs_to :greeter
21
- # delegate :hello, :to => :greeter
21
+ # delegate :hello, to: :greeter
22
22
  # end
23
23
  #
24
24
  # Foo.new.hello # => "hello"
@@ -28,7 +28,7 @@ class Module
28
28
  #
29
29
  # class Foo < ActiveRecord::Base
30
30
  # belongs_to :greeter
31
- # delegate :hello, :goodbye, :to => :greeter
31
+ # delegate :hello, :goodbye, to: :greeter
32
32
  # end
33
33
  #
34
34
  # Foo.new.goodbye # => "goodbye"
@@ -43,15 +43,27 @@ class Module
43
43
  # def initialize
44
44
  # @instance_array = [8,9,10,11]
45
45
  # end
46
- # delegate :sum, :to => :CONSTANT_ARRAY
47
- # delegate :min, :to => :@@class_array
48
- # delegate :max, :to => :@instance_array
46
+ # delegate :sum, to: :CONSTANT_ARRAY
47
+ # delegate :min, to: :@@class_array
48
+ # delegate :max, to: :@instance_array
49
49
  # end
50
50
  #
51
51
  # Foo.new.sum # => 6
52
52
  # Foo.new.min # => 4
53
53
  # Foo.new.max # => 11
54
54
  #
55
+ # It's also possible to delegate a method to the class by using +:class+:
56
+ #
57
+ # class Foo
58
+ # def self.hello
59
+ # "world"
60
+ # end
61
+ #
62
+ # delegate :hello, to: :class
63
+ # end
64
+ #
65
+ # Foo.new.hello # => "world"
66
+ #
55
67
  # Delegates can optionally be prefixed using the <tt>:prefix</tt> option. If the value
56
68
  # is <tt>true</tt>, the delegate methods are prefixed with the name of the object being
57
69
  # delegated to.
@@ -59,10 +71,10 @@ class Module
59
71
  # Person = Struct.new(:name, :address)
60
72
  #
61
73
  # class Invoice < Struct.new(:client)
62
- # delegate :name, :address, :to => :client, :prefix => true
74
+ # delegate :name, :address, to: :client, prefix: true
63
75
  # end
64
76
  #
65
- # john_doe = Person.new("John Doe", "Vimmersvej 13")
77
+ # john_doe = Person.new('John Doe', 'Vimmersvej 13')
66
78
  # invoice = Invoice.new(john_doe)
67
79
  # invoice.client_name # => "John Doe"
68
80
  # invoice.client_address # => "Vimmersvej 13"
@@ -70,49 +82,49 @@ class Module
70
82
  # It is also possible to supply a custom prefix.
71
83
  #
72
84
  # class Invoice < Struct.new(:client)
73
- # delegate :name, :address, :to => :client, :prefix => :customer
85
+ # delegate :name, :address, to: :client, prefix: :customer
74
86
  # end
75
87
  #
76
88
  # invoice = Invoice.new(john_doe)
77
- # invoice.customer_name # => "John Doe"
78
- # invoice.customer_address # => "Vimmersvej 13"
89
+ # invoice.customer_name # => 'John Doe'
90
+ # invoice.customer_address # => 'Vimmersvej 13'
79
91
  #
80
92
  # If the delegate object is +nil+ an exception is raised, and that happens
81
93
  # no matter whether +nil+ responds to the delegated method. You can get a
82
94
  # +nil+ instead with the +:allow_nil+ option.
83
95
  #
84
- # class Foo
85
- # attr_accessor :bar
86
- # def initialize(bar = nil)
87
- # @bar = bar
88
- # end
89
- # delegate :zoo, :to => :bar
90
- # end
91
- #
92
- # Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
96
+ # class Foo
97
+ # attr_accessor :bar
98
+ # def initialize(bar = nil)
99
+ # @bar = bar
100
+ # end
101
+ # delegate :zoo, to: :bar
102
+ # end
93
103
  #
94
- # class Foo
95
- # attr_accessor :bar
96
- # def initialize(bar = nil)
97
- # @bar = bar
98
- # end
99
- # delegate :zoo, :to => :bar, :allow_nil => true
100
- # end
104
+ # Foo.new.zoo # raises NoMethodError exception (you called nil.zoo)
101
105
  #
102
- # Foo.new.zoo # returns nil
106
+ # class Foo
107
+ # attr_accessor :bar
108
+ # def initialize(bar = nil)
109
+ # @bar = bar
110
+ # end
111
+ # delegate :zoo, to: :bar, allow_nil: true
112
+ # end
103
113
  #
114
+ # Foo.new.zoo # returns nil
104
115
  def delegate(*methods)
105
116
  options = methods.pop
106
117
  unless options.is_a?(Hash) && to = options[:to]
107
- raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)."
118
+ raise ArgumentError, 'Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, to: :greeter).'
108
119
  end
109
- prefix, to, allow_nil = options[:prefix], options[:to], options[:allow_nil]
110
120
 
111
- if prefix == true && to.to_s =~ /^[^a-z_]/
112
- raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
121
+ prefix, allow_nil = options.values_at(:prefix, :allow_nil)
122
+
123
+ if prefix == true && to =~ /^[^a-z_]/
124
+ raise ArgumentError, 'Can only automatically set the delegation prefix when delegating to a method.'
113
125
  end
114
126
 
115
- method_prefix =
127
+ method_prefix = \
116
128
  if prefix
117
129
  "#{prefix == true ? to : prefix}_"
118
130
  else
@@ -122,14 +134,19 @@ class Module
122
134
  file, line = caller.first.split(':', 2)
123
135
  line = line.to_i
124
136
 
137
+ to = to.to_s
138
+ to = 'self.class' if to == 'class'
139
+
125
140
  methods.each do |method|
126
- method = method.to_s
141
+ # Attribute writer methods only accept one argument. Makes sure []=
142
+ # methods still accept two arguments.
143
+ definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block'
127
144
 
128
145
  if allow_nil
129
146
  module_eval(<<-EOS, file, line - 2)
130
- def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block)
147
+ def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
131
148
  if #{to} || #{to}.respond_to?(:#{method}) # if client || client.respond_to?(:name)
132
- #{to}.__send__(:#{method}, *args, &block) # client.__send__(:name, *args, &block)
149
+ #{to}.#{method}(#{definition}) # client.name(*args, &block)
133
150
  end # end
134
151
  end # end
135
152
  EOS
@@ -137,8 +154,8 @@ class Module
137
154
  exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
138
155
 
139
156
  module_eval(<<-EOS, file, line - 1)
140
- def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block)
141
- #{to}.__send__(:#{method}, *args, &block) # client.__send__(:name, *args, &block)
157
+ def #{method_prefix}#{method}(#{definition}) # def customer_name(*args, &block)
158
+ #{to}.#{method}(#{definition}) # client.name(*args, &block)
142
159
  rescue NoMethodError # rescue NoMethodError
143
160
  if #{to}.nil? # if client.nil?
144
161
  #{exception} # # add helpful message to the exception