activesupport 3.2.22.5 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +364 -135
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -4
  5. data/lib/active_support/backtrace_cleaner.rb +33 -25
  6. data/lib/active_support/basic_object.rb +7 -17
  7. data/lib/active_support/benchmarkable.rb +19 -15
  8. data/lib/active_support/buffered_logger.rb +9 -113
  9. data/lib/active_support/cache/file_store.rb +14 -14
  10. data/lib/active_support/cache/mem_cache_store.rb +24 -30
  11. data/lib/active_support/cache/memory_store.rb +2 -0
  12. data/lib/active_support/cache/strategy/local_cache.rb +48 -37
  13. data/lib/active_support/cache.rb +228 -183
  14. data/lib/active_support/callbacks.rb +201 -253
  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/array/access.rb +17 -9
  19. data/lib/active_support/core_ext/array/conversions.rb +115 -55
  20. data/lib/active_support/core_ext/array/extract_options.rb +2 -2
  21. data/lib/active_support/core_ext/array/grouping.rb +21 -22
  22. data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
  23. data/lib/active_support/core_ext/array/wrap.rb +13 -16
  24. data/lib/active_support/core_ext/array.rb +0 -1
  25. data/lib/active_support/core_ext/benchmark.rb +7 -0
  26. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -24
  27. data/lib/active_support/core_ext/class/attribute.rb +40 -32
  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/calculations.rb +44 -187
  32. data/lib/active_support/core_ext/date/conversions.rb +16 -38
  33. data/lib/active_support/core_ext/date/zones.rb +25 -2
  34. data/lib/active_support/core_ext/date.rb +5 -0
  35. data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
  36. data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
  37. data/lib/active_support/core_ext/date_time/calculations.rb +77 -62
  38. data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
  39. data/lib/active_support/core_ext/date_time/zones.rb +11 -8
  40. data/lib/active_support/core_ext/date_time.rb +4 -0
  41. data/lib/active_support/core_ext/enumerable.rb +26 -73
  42. data/lib/active_support/core_ext/file/atomic.rb +27 -11
  43. data/lib/active_support/core_ext/file.rb +0 -1
  44. data/lib/active_support/core_ext/hash/conversions.rb +145 -79
  45. data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
  46. data/lib/active_support/core_ext/hash/diff.rb +5 -4
  47. data/lib/active_support/core_ext/hash/except.rb +1 -9
  48. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
  49. data/lib/active_support/core_ext/hash/keys.rb +108 -24
  50. data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
  51. data/lib/active_support/core_ext/hash/slice.rb +12 -12
  52. data/lib/active_support/core_ext/hash.rb +0 -1
  53. data/lib/active_support/core_ext/integer/inflections.rb +13 -1
  54. data/lib/active_support/core_ext/integer/time.rb +17 -12
  55. data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
  56. data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
  57. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
  58. data/lib/active_support/core_ext/load_error.rb +7 -5
  59. data/lib/active_support/core_ext/logger.rb +7 -23
  60. data/lib/active_support/core_ext/marshal.rb +21 -0
  61. data/lib/active_support/core_ext/module/aliasing.rb +8 -9
  62. data/lib/active_support/core_ext/module/anonymous.rb +2 -7
  63. data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
  64. data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
  65. data/lib/active_support/core_ext/module/delegation.rb +92 -49
  66. data/lib/active_support/core_ext/module/deprecation.rb +19 -3
  67. data/lib/active_support/core_ext/module/introspection.rb +17 -27
  68. data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
  69. data/lib/active_support/core_ext/module/remove_method.rb +1 -5
  70. data/lib/active_support/core_ext/module.rb +1 -3
  71. data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
  72. data/lib/active_support/core_ext/numeric/time.rb +6 -6
  73. data/lib/active_support/core_ext/numeric.rb +1 -0
  74. data/lib/active_support/core_ext/object/acts_like.rb +4 -4
  75. data/lib/active_support/core_ext/object/blank.rb +7 -23
  76. data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
  77. data/lib/active_support/core_ext/object/duplicable.rb +1 -30
  78. data/lib/active_support/core_ext/object/inclusion.rb +8 -7
  79. data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
  80. data/lib/active_support/core_ext/object/to_json.rb +8 -0
  81. data/lib/active_support/core_ext/object/to_param.rb +5 -2
  82. data/lib/active_support/core_ext/object/try.rb +46 -25
  83. data/lib/active_support/core_ext/object/with_options.rb +7 -8
  84. data/lib/active_support/core_ext/object.rb +1 -0
  85. data/lib/active_support/core_ext/proc.rb +3 -0
  86. data/lib/active_support/core_ext/range/conversions.rb +0 -2
  87. data/lib/active_support/core_ext/range/include_range.rb +3 -1
  88. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  89. data/lib/active_support/core_ext/range.rb +0 -2
  90. data/lib/active_support/core_ext/string/access.rb +95 -90
  91. data/lib/active_support/core_ext/string/conversions.rb +27 -38
  92. data/lib/active_support/core_ext/string/encoding.rb +6 -9
  93. data/lib/active_support/core_ext/string/filters.rb +24 -18
  94. data/lib/active_support/core_ext/string/indent.rb +43 -0
  95. data/lib/active_support/core_ext/string/inflections.rb +70 -60
  96. data/lib/active_support/core_ext/string/inquiry.rb +2 -2
  97. data/lib/active_support/core_ext/string/multibyte.rb +41 -64
  98. data/lib/active_support/core_ext/string/output_safety.rb +59 -51
  99. data/lib/active_support/core_ext/string/zones.rb +13 -0
  100. data/lib/active_support/core_ext/string.rb +2 -3
  101. data/lib/active_support/core_ext/struct.rb +6 -0
  102. data/lib/active_support/core_ext/thread.rb +74 -0
  103. data/lib/active_support/core_ext/time/calculations.rb +108 -184
  104. data/lib/active_support/core_ext/time/conversions.rb +27 -51
  105. data/lib/active_support/core_ext/time/marshal.rb +0 -27
  106. data/lib/active_support/core_ext/time/zones.rb +27 -17
  107. data/lib/active_support/core_ext/time.rb +5 -0
  108. data/lib/active_support/core_ext/uri.rb +13 -17
  109. data/lib/active_support/core_ext.rb +3 -2
  110. data/lib/active_support/dependencies/autoload.rb +47 -20
  111. data/lib/active_support/dependencies.rb +160 -141
  112. data/lib/active_support/deprecation/behaviors.rb +44 -30
  113. data/lib/active_support/deprecation/instance_delegator.rb +24 -0
  114. data/lib/active_support/deprecation/method_wrappers.rb +33 -18
  115. data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
  116. data/lib/active_support/deprecation/reporting.rb +40 -11
  117. data/lib/active_support/deprecation.rb +39 -14
  118. data/lib/active_support/descendants_tracker.rb +34 -19
  119. data/lib/active_support/duration.rb +6 -8
  120. data/lib/active_support/file_update_checker.rb +63 -47
  121. data/lib/active_support/gzip.rb +11 -5
  122. data/lib/active_support/hash_with_indifferent_access.rb +127 -42
  123. data/lib/active_support/i18n.rb +4 -0
  124. data/lib/active_support/i18n_railtie.rb +5 -22
  125. data/lib/active_support/inflections.rb +14 -12
  126. data/lib/active_support/inflector/inflections.rb +108 -71
  127. data/lib/active_support/inflector/methods.rb +181 -160
  128. data/lib/active_support/inflector/transliterate.rb +16 -17
  129. data/lib/active_support/json/decoding.rb +18 -17
  130. data/lib/active_support/json/encoding.rb +93 -39
  131. data/lib/active_support/json/variable.rb +10 -1
  132. data/lib/active_support/key_generator.rb +75 -0
  133. data/lib/active_support/lazy_load_hooks.rb +21 -19
  134. data/lib/active_support/locale/en.yml +100 -3
  135. data/lib/active_support/log_subscriber/test_helper.rb +18 -15
  136. data/lib/active_support/log_subscriber.rb +35 -52
  137. data/lib/active_support/logger.rb +57 -0
  138. data/lib/active_support/logger_silence.rb +24 -0
  139. data/lib/active_support/message_encryptor.rb +38 -35
  140. data/lib/active_support/message_verifier.rb +9 -15
  141. data/lib/active_support/multibyte/chars.rb +80 -333
  142. data/lib/active_support/multibyte/unicode.rb +74 -64
  143. data/lib/active_support/multibyte.rb +5 -28
  144. data/lib/active_support/notifications/fanout.rb +112 -18
  145. data/lib/active_support/notifications/instrumenter.rb +33 -14
  146. data/lib/active_support/notifications.rb +79 -26
  147. data/lib/active_support/number_helper.rb +637 -0
  148. data/lib/active_support/ordered_hash.rb +8 -190
  149. data/lib/active_support/ordered_options.rb +21 -23
  150. data/lib/active_support/per_thread_registry.rb +52 -0
  151. data/lib/active_support/proxy_object.rb +13 -0
  152. data/lib/active_support/rails.rb +27 -0
  153. data/lib/active_support/railtie.rb +12 -32
  154. data/lib/active_support/rescuable.rb +9 -4
  155. data/lib/active_support/string_inquirer.rb +13 -8
  156. data/lib/active_support/subscriber.rb +93 -0
  157. data/lib/active_support/tagged_logging.rb +51 -73
  158. data/lib/active_support/test_case.rb +46 -17
  159. data/lib/active_support/testing/assertions.rb +56 -26
  160. data/lib/active_support/testing/autorun.rb +5 -0
  161. data/lib/active_support/testing/constant_lookup.rb +54 -0
  162. data/lib/active_support/testing/declarative.rb +1 -1
  163. data/lib/active_support/testing/deprecation.rb +0 -19
  164. data/lib/active_support/testing/isolation.rb +29 -58
  165. data/lib/active_support/testing/pending.rb +5 -43
  166. data/lib/active_support/testing/setup_and_teardown.rb +6 -92
  167. data/lib/active_support/testing/tagged_logging.rb +25 -0
  168. data/lib/active_support/time.rb +6 -21
  169. data/lib/active_support/time_with_zone.rb +80 -43
  170. data/lib/active_support/values/time_zone.rb +81 -60
  171. data/lib/active_support/values/unicode_tables.dat +0 -0
  172. data/lib/active_support/version.rb +7 -6
  173. data/lib/active_support/xml_mini/jdom.rb +9 -11
  174. data/lib/active_support/xml_mini/libxml.rb +1 -2
  175. data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
  176. data/lib/active_support/xml_mini/nokogiri.rb +1 -2
  177. data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
  178. data/lib/active_support/xml_mini/rexml.rb +6 -8
  179. data/lib/active_support/xml_mini.rb +35 -17
  180. data/lib/active_support.rb +8 -21
  181. metadata +104 -72
  182. data/lib/active_support/base64.rb +0 -54
  183. data/lib/active_support/core_ext/array/random_access.rb +0 -30
  184. data/lib/active_support/core_ext/date/freeze.rb +0 -33
  185. data/lib/active_support/core_ext/exception.rb +0 -3
  186. data/lib/active_support/core_ext/file/path.rb +0 -5
  187. data/lib/active_support/core_ext/float/rounding.rb +0 -19
  188. data/lib/active_support/core_ext/float.rb +0 -1
  189. data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
  190. data/lib/active_support/core_ext/io.rb +0 -15
  191. data/lib/active_support/core_ext/module/method_names.rb +0 -14
  192. data/lib/active_support/core_ext/module/synchronization.rb +0 -45
  193. data/lib/active_support/core_ext/process/daemon.rb +0 -23
  194. data/lib/active_support/core_ext/process.rb +0 -1
  195. data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
  196. data/lib/active_support/core_ext/range/cover.rb +0 -3
  197. data/lib/active_support/core_ext/rexml.rb +0 -46
  198. data/lib/active_support/core_ext/string/interpolation.rb +0 -2
  199. data/lib/active_support/core_ext/string/xchar.rb +0 -18
  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/jruby.rb +0 -115
  208. data/lib/active_support/testing/performance/rubinius.rb +0 -113
  209. data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
  210. data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
  211. data/lib/active_support/testing/performance/ruby.rb +0 -152
  212. data/lib/active_support/testing/performance.rb +0 -317
  213. data/lib/active_support/time/autoload.rb +0 -5
  214. data/lib/active_support/whiny_nil.rb +0 -24
@@ -1,16 +1,19 @@
1
1
  class Array
2
- # Returns an unique array based on the criteria given as a +Proc+.
2
+ # *DEPRECATED*: Use <tt>Array#uniq</tt> instead.
3
3
  #
4
- # [1, 2, 3, 4].uniq_by { |i| i.odd? } # => [1, 2]
4
+ # Returns a unique array based on the criteria in the block.
5
5
  #
6
- def uniq_by
7
- hash, array = {}, []
8
- each { |i| hash[yield(i)] ||= (array << i) }
9
- array
6
+ # [1, 2, 3, 4].uniq_by { |i| i.odd? } # => [1, 2]
7
+ def uniq_by(&block)
8
+ ActiveSupport::Deprecation.warn 'uniq_by is deprecated. Use Array#uniq instead'
9
+ uniq(&block)
10
10
  end
11
11
 
12
- # Same as uniq_by, but modifies self.
13
- def uniq_by!
14
- replace(uniq_by{ |i| yield(i) })
12
+ # *DEPRECATED*: Use <tt>Array#uniq!</tt> instead.
13
+ #
14
+ # Same as +uniq_by+, but modifies +self+.
15
+ def uniq_by!(&block)
16
+ ActiveSupport::Deprecation.warn 'uniq_by! is deprecated. Use Array#uniq! instead'
17
+ uniq!(&block)
15
18
  end
16
19
  end
@@ -7,35 +7,32 @@ class Array
7
7
  # * Otherwise, if the argument responds to +to_ary+ it is invoked, and its result returned.
8
8
  # * Otherwise, returns an array with the argument as its single element.
9
9
  #
10
- # Array.wrap(nil) # => []
11
- # Array.wrap([1, 2, 3]) # => [1, 2, 3]
12
- # Array.wrap(0) # => [0]
10
+ # Array.wrap(nil) # => []
11
+ # Array.wrap([1, 2, 3]) # => [1, 2, 3]
12
+ # Array.wrap(0) # => [0]
13
13
  #
14
14
  # This method is similar in purpose to <tt>Kernel#Array</tt>, but there are some differences:
15
15
  #
16
16
  # * If the argument responds to +to_ary+ the method is invoked. <tt>Kernel#Array</tt>
17
- # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
18
- # such a +nil+ right away.
17
+ # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
18
+ # +nil+ right away.
19
19
  # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
20
- # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
21
- # * It does not call +to_a+ on the argument, though special-cases +nil+ to return an empty array.
20
+ # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
21
+ # * It does not call +to_a+ on the argument, but returns an empty array if argument is +nil+.
22
22
  #
23
- # The last point is particularly worth comparing for some enumerables:
23
+ # The second point is easily explained with some enumerables:
24
24
  #
25
- # Array(:foo => :bar) # => [[:foo, :bar]]
26
- # Array.wrap(:foo => :bar) # => [{:foo => :bar}]
27
- #
28
- # Array("foo\nbar") # => ["foo\n", "bar"], in Ruby 1.8
29
- # Array.wrap("foo\nbar") # => ["foo\nbar"]
25
+ # Array(foo: :bar) # => [[:foo, :bar]]
26
+ # Array.wrap(foo: :bar) # => [{:foo=>:bar}]
30
27
  #
31
28
  # There's also a related idiom that uses the splat operator:
32
29
  #
33
30
  # [*object]
34
31
  #
35
- # which returns <tt>[nil]</tt> for +nil+, and calls to <tt>Array(object)</tt> otherwise.
32
+ # which returns <tt>[]</tt> for +nil+, but calls to <tt>Array(object)</tt> otherwise.
36
33
  #
37
- # Thus, in this case the behavior is different for +nil+, and the differences with
38
- # <tt>Kernel#Array</tt> explained above apply to the rest of +object+s.
34
+ # The differences with <tt>Kernel#Array</tt> explained above
35
+ # apply to the rest of <tt>object</tt>s.
39
36
  def self.wrap(object)
40
37
  if object.nil?
41
38
  []
@@ -4,5 +4,4 @@ require 'active_support/core_ext/array/uniq_by'
4
4
  require 'active_support/core_ext/array/conversions'
5
5
  require 'active_support/core_ext/array/extract_options'
6
6
  require 'active_support/core_ext/array/grouping'
7
- require 'active_support/core_ext/array/random_access'
8
7
  require 'active_support/core_ext/array/prepend_and_append'
@@ -1,6 +1,13 @@
1
1
  require 'benchmark'
2
2
 
3
3
  class << Benchmark
4
+ # Benchmark realtime in milliseconds.
5
+ #
6
+ # Benchmark.realtime { User.all }
7
+ # # => 8.0e-05
8
+ #
9
+ # Benchmark.ms { User.all }
10
+ # # => 0.074
4
11
  def ms
5
12
  1000 * realtime { yield }
6
13
  end
@@ -1,31 +1,10 @@
1
1
  require 'bigdecimal'
2
-
3
- begin
4
- require 'psych'
5
- rescue LoadError
6
- end
7
-
2
+ require 'bigdecimal/util'
8
3
  require 'yaml'
9
4
 
10
5
  class BigDecimal
11
- YAML_TAG = 'tag:yaml.org,2002:float'
12
6
  YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }
13
7
 
14
- # This emits the number without any scientific notation.
15
- # This is better than self.to_f.to_s since it doesn't lose precision.
16
- #
17
- # Note that reconstituting YAML floats to native floats may lose precision.
18
- def to_yaml(opts = {})
19
- return super if
20
- (defined?(YAML::ENGINE) && !YAML::ENGINE.syck?) ||
21
- (defined?(Psych) && YAML == Psych)
22
-
23
- YAML.quick_emit(nil, opts) do |out|
24
- string = to_s
25
- out.scalar(YAML_TAG, YAML_MAPPING[string] || string, :plain)
26
- end
27
- end
28
-
29
8
  def encode_with(coder)
30
9
  string = to_s
31
10
  coder.represent_scalar(nil, YAML_MAPPING[string] || string)
@@ -39,8 +18,13 @@ class BigDecimal
39
18
  end
40
19
 
41
20
  DEFAULT_STRING_FORMAT = 'F'
42
- def to_formatted_s(format = DEFAULT_STRING_FORMAT)
43
- _original_to_s(format)
21
+ def to_formatted_s(*args)
22
+ if args[0].is_a?(Symbol)
23
+ super
24
+ else
25
+ format = args[0] || DEFAULT_STRING_FORMAT
26
+ _original_to_s(format)
27
+ end
44
28
  end
45
29
  alias_method :_original_to_s, :to_s
46
30
  alias_method :to_s, :to_formatted_s
@@ -44,7 +44,8 @@ class Class
44
44
  # Base.setting # => []
45
45
  # Subclass.setting # => [:foo]
46
46
  #
47
- # For convenience, a query method is defined as well:
47
+ # For convenience, an instance predicate method is defined as well.
48
+ # To skip it, pass <tt>instance_predicate: false</tt>.
48
49
  #
49
50
  # Subclass.setting? # => false
50
51
  #
@@ -57,61 +58,68 @@ class Class
57
58
  # object.setting # => false
58
59
  # Base.setting # => true
59
60
  #
60
- # To opt out of the instance reader method, pass :instance_reader => false.
61
+ # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
61
62
  #
62
63
  # object.setting # => NoMethodError
63
64
  # object.setting? # => NoMethodError
64
65
  #
65
- # To opt out of the instance writer method, pass :instance_writer => false.
66
+ # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
66
67
  #
67
68
  # object.setting = false # => NoMethodError
69
+ #
70
+ # To opt out of both instance methods, pass <tt>instance_accessor: false</tt>.
68
71
  def class_attribute(*attrs)
69
72
  options = attrs.extract_options!
70
- instance_reader = instance_reader = options.fetch(:instance_reader, true)
71
- instance_writer = options.fetch(:instance_writer, true)
73
+ # double assignment is used to avoid "assigned but unused variable" warning
74
+ instance_reader = instance_reader = options.fetch(:instance_accessor, true) && options.fetch(:instance_reader, true)
75
+ instance_writer = options.fetch(:instance_accessor, true) && options.fetch(:instance_writer, true)
76
+ instance_predicate = options.fetch(:instance_predicate, true)
72
77
 
73
78
  attrs.each do |name|
74
- class_eval <<-RUBY, __FILE__, __LINE__ + 1
75
- def self.#{name}() nil end
76
- def self.#{name}?() !!#{name} end
79
+ define_singleton_method(name) { nil }
80
+ define_singleton_method("#{name}?") { !!public_send(name) } if instance_predicate
77
81
 
78
- def self.#{name}=(val)
79
- singleton_class.class_eval do
80
- remove_possible_method(:#{name})
81
- define_method(:#{name}) { val }
82
- end
82
+ ivar = "@#{name}"
83
83
 
84
- if singleton_class?
85
- class_eval do
86
- remove_possible_method(:#{name})
87
- def #{name}
88
- defined?(@#{name}) ? @#{name} : singleton_class.#{name}
84
+ define_singleton_method("#{name}=") do |val|
85
+ singleton_class.class_eval do
86
+ remove_possible_method(name)
87
+ define_method(name) { val }
88
+ end
89
+
90
+ if singleton_class?
91
+ class_eval do
92
+ remove_possible_method(name)
93
+ define_method(name) do
94
+ if instance_variable_defined? ivar
95
+ instance_variable_get ivar
96
+ else
97
+ singleton_class.send name
89
98
  end
90
99
  end
91
100
  end
92
- val
93
101
  end
102
+ val
103
+ end
94
104
 
95
- if instance_reader
96
- remove_possible_method :#{name}
97
- def #{name}
98
- defined?(@#{name}) ? @#{name} : self.class.#{name}
99
- end
100
-
101
- def #{name}?
102
- !!#{name}
105
+ if instance_reader
106
+ remove_possible_method name
107
+ define_method(name) do
108
+ if instance_variable_defined?(ivar)
109
+ instance_variable_get ivar
110
+ else
111
+ self.class.public_send name
103
112
  end
104
113
  end
105
- RUBY
114
+ define_method("#{name}?") { !!public_send(name) } if instance_predicate
115
+ end
106
116
 
107
117
  attr_writer name if instance_writer
108
118
  end
109
119
  end
110
120
 
111
121
  private
112
- unless respond_to?(:singleton_class?)
113
- def singleton_class?
114
- ancestors.first != self
115
- end
122
+ def singleton_class?
123
+ ancestors.first != self
116
124
  end
117
125
  end
@@ -21,17 +21,18 @@ class Class
21
21
  # end
22
22
  # # => NameError: invalid attribute name
23
23
  #
24
- # If you want to opt out the instance reader method, you can pass <tt>:instance_reader => false</tt>
25
- # or <tt>:instance_accessor => false</tt>.
24
+ # If you want to opt out the instance reader method, you can pass <tt>instance_reader: false</tt>
25
+ # or <tt>instance_accessor: false</tt>.
26
26
  #
27
27
  # class Person
28
- # cattr_reader :hair_colors, :instance_reader => false
28
+ # cattr_reader :hair_colors, instance_reader: false
29
29
  # end
30
30
  #
31
31
  # Person.new.hair_colors # => NoMethodError
32
32
  def cattr_reader(*syms)
33
33
  options = syms.extract_options!
34
34
  syms.each do |sym|
35
+ raise NameError.new("invalid class attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
35
36
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
36
37
  unless defined? @@#{sym}
37
38
  @@#{sym} = nil
@@ -71,11 +72,11 @@ class Class
71
72
  # end
72
73
  # # => NameError: invalid attribute name
73
74
  #
74
- # If you want to opt out the instance writer method, pass <tt>:instance_writer => false</tt>
75
- # or <tt>:instance_accessor => false</tt>.
75
+ # If you want to opt out the instance writer method, pass <tt>instance_writer: false</tt>
76
+ # or <tt>instance_accessor: false</tt>.
76
77
  #
77
78
  # class Person
78
- # cattr_writer :hair_colors, :instance_writer => false
79
+ # cattr_writer :hair_colors, instance_writer: false
79
80
  # end
80
81
  #
81
82
  # Person.new.hair_colors = [:blonde, :red] # => NoMethodError
@@ -92,6 +93,7 @@ class Class
92
93
  def cattr_writer(*syms)
93
94
  options = syms.extract_options!
94
95
  syms.each do |sym|
96
+ raise NameError.new("invalid class attribute name: #{sym}") unless sym =~ /^[_A-Za-z]\w*$/
95
97
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
96
98
  unless defined? @@#{sym}
97
99
  @@#{sym} = nil
@@ -109,7 +111,7 @@ class Class
109
111
  end
110
112
  EOS
111
113
  end
112
- self.send("#{sym}=", yield) if block_given?
114
+ send("#{sym}=", yield) if block_given?
113
115
  end
114
116
  end
115
117
 
@@ -133,20 +135,20 @@ class Class
133
135
  # Male.hair_colors << :blue
134
136
  # Person.hair_colors # => [:brown, :black, :blonde, :red, :blue]
135
137
  #
136
- # To opt out of the instance writer method, pass <tt>:instance_writer => false</tt>.
137
- # To opt out of the instance reader method, pass <tt>:instance_reader => false</tt>.
138
+ # To opt out of the instance writer method, pass <tt>instance_writer: false</tt>.
139
+ # To opt out of the instance reader method, pass <tt>instance_reader: false</tt>.
138
140
  #
139
141
  # class Person
140
- # cattr_accessor :hair_colors, :instance_writer => false, :instance_reader => false
142
+ # cattr_accessor :hair_colors, instance_writer: false, instance_reader: false
141
143
  # end
142
144
  #
143
145
  # Person.new.hair_colors = [:brown] # => NoMethodError
144
146
  # Person.new.hair_colors # => NoMethodError
145
147
  #
146
- # Or pass <tt>:instance_accessor => false</tt>, to opt out both instance methods.
148
+ # Or pass <tt>instance_accessor: false</tt>, to opt out both instance methods.
147
149
  #
148
150
  # class Person
149
- # cattr_accessor :hair_colors, :instance_accessor => false
151
+ # cattr_accessor :hair_colors, instance_accessor: false
150
152
  # end
151
153
  #
152
154
  # Person.new.hair_colors = [:brown] # => NoMethodError
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/object/blank'
2
- require 'active_support/core_ext/array/extract_options'
3
1
  require 'active_support/core_ext/kernel/singleton_class'
4
2
  require 'active_support/core_ext/module/remove_method'
5
3
 
@@ -22,23 +20,21 @@ class Class
22
20
  define_method("#{name}?") { !!send("#{name}") } if options[:instance_reader] != false
23
21
  end
24
22
 
25
- private
26
-
27
- # Take the object being set and store it in a method. This gives us automatic
28
- # inheritance behavior, without having to store the object in an instance
29
- # variable and look up the superclass chain manually.
30
- def _stash_object_in_method(object, method, instance_reader = true)
31
- singleton_class.remove_possible_method(method)
32
- singleton_class.send(:define_method, method) { object }
33
- remove_possible_method(method)
34
- define_method(method) { object } if instance_reader
35
- end
36
-
37
- def _superclass_delegating_accessor(name, options = {})
38
- singleton_class.send(:define_method, "#{name}=") do |value|
39
- _stash_object_in_method(value, name, options[:instance_reader] != false)
23
+ private
24
+ # Take the object being set and store it in a method. This gives us automatic
25
+ # inheritance behavior, without having to store the object in an instance
26
+ # variable and look up the superclass chain manually.
27
+ def _stash_object_in_method(object, method, instance_reader = true)
28
+ singleton_class.remove_possible_method(method)
29
+ singleton_class.send(:define_method, method) { object }
30
+ remove_possible_method(method)
31
+ define_method(method) { object } if instance_reader
40
32
  end
41
- send("#{name}=", nil)
42
- end
43
33
 
34
+ def _superclass_delegating_accessor(name, options = {})
35
+ singleton_class.send(:define_method, "#{name}=") do |value|
36
+ _stash_object_in_method(value, name, options[:instance_reader] != false)
37
+ end
38
+ send("#{name}=", nil)
39
+ end
44
40
  end
@@ -1,19 +1,19 @@
1
1
  require 'active_support/core_ext/module/anonymous'
2
2
  require 'active_support/core_ext/module/reachable'
3
3
 
4
- class Class #:nodoc:
4
+ class Class
5
5
  begin
6
6
  ObjectSpace.each_object(Class.new) {}
7
7
 
8
- def descendants
8
+ def descendants # :nodoc:
9
9
  descendants = []
10
- ObjectSpace.each_object(class << self; self; end) do |k|
10
+ ObjectSpace.each_object(singleton_class) do |k|
11
11
  descendants.unshift k unless k == self
12
12
  end
13
13
  descendants
14
14
  end
15
15
  rescue StandardError # JRuby
16
- def descendants
16
+ def descendants # :nodoc:
17
17
  descendants = []
18
18
  ObjectSpace.each_object(Class) do |k|
19
19
  descendants.unshift k if k < self
@@ -25,7 +25,13 @@ class Class #:nodoc:
25
25
 
26
26
  # Returns an array with the direct children of +self+.
27
27
  #
28
- # Integer.subclasses # => [Bignum, Fixnum]
28
+ # Integer.subclasses # => [Fixnum, Bignum]
29
+ #
30
+ # class Foo; end
31
+ # class Bar < Foo; end
32
+ # class Baz < Bar; end
33
+ #
34
+ # Foo.subclasses # => [Bar]
29
35
  def subclasses
30
36
  subclasses, chain = [], descendants
31
37
  chain.each do |k|