activesupport 3.0.20 → 3.1.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 (132) hide show
  1. data/CHANGELOG +24 -28
  2. data/README.rdoc +2 -2
  3. data/lib/active_support/backtrace_cleaner.rb +17 -12
  4. data/lib/active_support/buffered_logger.rb +7 -9
  5. data/lib/active_support/cache/file_store.rb +4 -3
  6. data/lib/active_support/cache/mem_cache_store.rb +10 -2
  7. data/lib/active_support/cache/strategy/local_cache.rb +28 -23
  8. data/lib/active_support/cache.rb +11 -14
  9. data/lib/active_support/callbacks.rb +195 -175
  10. data/lib/active_support/concern.rb +105 -35
  11. data/lib/active_support/configurable.rb +50 -8
  12. data/lib/active_support/core_ext/array/access.rb +2 -2
  13. data/lib/active_support/core_ext/array/conversions.rb +2 -2
  14. data/lib/active_support/core_ext/array/random_access.rb +10 -7
  15. data/lib/active_support/core_ext/array/uniq_by.rb +2 -3
  16. data/lib/active_support/core_ext/array/wrap.rb +1 -1
  17. data/lib/active_support/core_ext/big_decimal/conversions.rb +0 -2
  18. data/lib/active_support/core_ext/class/attribute.rb +15 -1
  19. data/lib/active_support/core_ext/class/inheritable_attributes.rb +10 -86
  20. data/lib/active_support/core_ext/class/subclasses.rb +20 -34
  21. data/lib/active_support/core_ext/date/calculations.rb +17 -5
  22. data/lib/active_support/core_ext/date/conversions.rb +9 -2
  23. data/lib/active_support/core_ext/date_time/calculations.rb +26 -9
  24. data/lib/active_support/core_ext/date_time/conversions.rb +9 -9
  25. data/lib/active_support/core_ext/date_time/zones.rb +1 -1
  26. data/lib/active_support/core_ext/enumerable.rb +3 -6
  27. data/lib/active_support/core_ext/float/rounding.rb +1 -1
  28. data/lib/active_support/core_ext/hash/conversions.rb +22 -34
  29. data/lib/active_support/core_ext/hash/deep_dup.rb +11 -0
  30. data/lib/active_support/core_ext/hash/indifferent_access.rb +12 -0
  31. data/lib/active_support/core_ext/hash/keys.rb +6 -4
  32. data/lib/active_support/core_ext/hash/reverse_merge.rb +9 -14
  33. data/lib/active_support/core_ext/hash/slice.rb +3 -1
  34. data/lib/active_support/core_ext/hash.rb +1 -0
  35. data/lib/active_support/core_ext/integer/inflections.rb +7 -4
  36. data/lib/active_support/core_ext/kernel/reporting.rb +31 -0
  37. data/lib/active_support/core_ext/kernel/requires.rb +2 -0
  38. data/lib/active_support/core_ext/logger.rb +11 -38
  39. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +12 -12
  40. data/lib/active_support/core_ext/module/attr_internal.rb +13 -6
  41. data/lib/active_support/core_ext/module/delegation.rb +1 -5
  42. data/lib/active_support/core_ext/module/remove_method.rb +7 -2
  43. data/lib/active_support/core_ext/numeric/time.rb +2 -0
  44. data/lib/active_support/core_ext/object/blank.rb +45 -12
  45. data/lib/active_support/core_ext/object/duplicable.rb +50 -9
  46. data/lib/active_support/core_ext/object/inclusion.rb +15 -0
  47. data/lib/active_support/core_ext/object/instance_variables.rb +1 -35
  48. data/lib/active_support/core_ext/object/to_param.rb +13 -8
  49. data/lib/active_support/core_ext/object/to_query.rb +2 -2
  50. data/lib/active_support/core_ext/object/try.rb +29 -10
  51. data/lib/active_support/core_ext/object/with_options.rb +25 -8
  52. data/lib/active_support/core_ext/object.rb +1 -1
  53. data/lib/active_support/core_ext/range/cover.rb +3 -0
  54. data/lib/active_support/core_ext/range.rb +1 -0
  55. data/lib/active_support/core_ext/string/behavior.rb +1 -2
  56. data/lib/active_support/core_ext/string/conversions.rb +1 -0
  57. data/lib/active_support/core_ext/string/exclude.rb +1 -1
  58. data/lib/active_support/core_ext/string/filters.rb +3 -3
  59. data/lib/active_support/core_ext/string/inflections.rb +1 -1
  60. data/lib/active_support/core_ext/string/inquiry.rb +13 -0
  61. data/lib/active_support/core_ext/string/multibyte.rb +2 -2
  62. data/lib/active_support/core_ext/string/output_safety.rb +45 -62
  63. data/lib/active_support/core_ext/string.rb +1 -0
  64. data/lib/active_support/core_ext/time/calculations.rb +19 -16
  65. data/lib/active_support/core_ext/time/conversions.rb +2 -24
  66. data/lib/active_support/core_ext/time/zones.rb +32 -21
  67. data/lib/active_support/core_ext/uri.rb +8 -0
  68. data/lib/active_support/dependencies.rb +74 -28
  69. data/lib/active_support/deprecation/behaviors.rb +7 -0
  70. data/lib/active_support/deprecation/proxy_wrappers.rb +1 -1
  71. data/lib/active_support/deprecation/reporting.rb +4 -0
  72. data/lib/active_support/deprecation.rb +2 -2
  73. data/lib/active_support/descendants_tracker.rb +9 -7
  74. data/lib/active_support/duration.rb +5 -0
  75. data/lib/active_support/file_update_checker.rb +1 -1
  76. data/lib/active_support/file_watcher.rb +36 -0
  77. data/lib/active_support/hash_with_indifferent_access.rb +20 -8
  78. data/lib/active_support/i18n.rb +0 -1
  79. data/lib/active_support/i18n_railtie.rb +2 -2
  80. data/lib/active_support/inflections.rb +1 -0
  81. data/lib/active_support/inflector/inflections.rb +1 -1
  82. data/lib/active_support/inflector/methods.rb +5 -3
  83. data/lib/active_support/json/decoding.rb +37 -23
  84. data/lib/active_support/json/encoding.rb +12 -4
  85. data/lib/active_support/lazy_load_hooks.rb +7 -7
  86. data/lib/active_support/log_subscriber/test_helper.rb +5 -3
  87. data/lib/active_support/log_subscriber.rb +6 -6
  88. data/lib/active_support/message_encryptor.rb +1 -1
  89. data/lib/active_support/message_verifier.rb +1 -1
  90. data/lib/active_support/multibyte/chars.rb +5 -5
  91. data/lib/active_support/multibyte/unicode.rb +2 -1
  92. data/lib/active_support/notifications/fanout.rb +3 -3
  93. data/lib/active_support/notifications/instrumenter.rb +1 -1
  94. data/lib/active_support/notifications.rb +9 -10
  95. data/lib/active_support/ordered_hash.rb +23 -2
  96. data/lib/active_support/ordered_options.rb +37 -3
  97. data/lib/active_support/railtie.rb +1 -1
  98. data/lib/active_support/rescuable.rb +1 -0
  99. data/lib/active_support/secure_random.rb +3 -196
  100. data/lib/active_support/test_case.rb +2 -10
  101. data/lib/active_support/testing/assertions.rb +20 -7
  102. data/lib/active_support/testing/mochaing.rb +7 -0
  103. data/lib/active_support/testing/pending.rb +27 -23
  104. data/lib/active_support/testing/performance/jruby.rb +115 -0
  105. data/lib/active_support/testing/performance/rubinius.rb +113 -0
  106. data/lib/active_support/testing/performance/ruby/mri.rb +57 -0
  107. data/lib/active_support/testing/performance/ruby/yarv.rb +57 -0
  108. data/lib/active_support/testing/performance/ruby.rb +152 -0
  109. data/lib/active_support/testing/performance.rb +214 -322
  110. data/lib/active_support/testing/setup_and_teardown.rb +8 -11
  111. data/lib/active_support/time_with_zone.rb +6 -3
  112. data/lib/active_support/values/time_zone.rb +26 -8
  113. data/lib/active_support/version.rb +2 -2
  114. data/lib/active_support/whiny_nil.rb +1 -1
  115. data/lib/active_support/xml_mini/jdom.rb +1 -1
  116. data/lib/active_support/xml_mini/libxml.rb +1 -0
  117. data/lib/active_support/xml_mini/libxmlsax.rb +2 -1
  118. data/lib/active_support/xml_mini/nokogiri.rb +1 -0
  119. data/lib/active_support/xml_mini/nokogirisax.rb +1 -0
  120. data/lib/active_support/xml_mini/rexml.rb +1 -0
  121. data/lib/active_support/xml_mini.rb +8 -3
  122. data/lib/active_support.rb +4 -2
  123. metadata +70 -32
  124. checksums.yaml +0 -7
  125. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +0 -19
  126. data/lib/active_support/core_ext/cgi.rb +0 -1
  127. data/lib/active_support/core_ext/object/returning.rb +0 -43
  128. data/lib/active_support/json/backends/jsongem.rb +0 -47
  129. data/lib/active_support/json/backends/okjson.rb +0 -644
  130. data/lib/active_support/json/backends/yajl.rb +0 -44
  131. data/lib/active_support/json/backends/yaml.rb +0 -19
  132. data/lib/active_support/testing/default.rb +0 -9
@@ -1,39 +1,109 @@
1
- # A typical module looks like this
2
- #
3
- # module M
4
- # def self.included(base)
5
- # base.send(:extend, ClassMethods)
6
- # base.send(:include, InstanceMethods)
7
- # scope :foo, :conditions => { :created_at => nil }
8
- # end
9
- #
10
- # module ClassMethods
11
- # def cm; puts 'I am a class method'; end
12
- # end
13
- #
14
- # module InstanceMethods
15
- # def im; puts 'I am an instance method'; end
16
- # end
17
- # end
18
- #
19
- # By using <tt>ActiveSupport::Concern</tt> the above module could instead be written as:
20
- #
21
- # module M
22
- # extend ActiveSupport::Concern
23
- #
24
- # included do
25
- # scope :foo, :conditions => { :created_at => nil }
26
- # end
27
- #
28
- # module ClassMethods
29
- # def cm; puts 'I am a class method'; end
30
- # end
31
- #
32
- # module InstanceMethods
33
- # def im; puts 'I am an instance method'; end
34
- # end
35
- # end
36
1
  module ActiveSupport
2
+ # A typical module looks like this:
3
+ #
4
+ # module M
5
+ # def self.included(base)
6
+ # base.extend ClassMethods
7
+ # base.send(:include, InstanceMethods)
8
+ # scope :disabled, where(:disabled => true)
9
+ # end
10
+ #
11
+ # module ClassMethods
12
+ # ...
13
+ # end
14
+ #
15
+ # module InstanceMethods
16
+ # ...
17
+ # end
18
+ # end
19
+ #
20
+ # By using <tt>ActiveSupport::Concern</tt> the above module could instead be written as:
21
+ #
22
+ # require 'active_support/concern'
23
+ #
24
+ # module M
25
+ # extend ActiveSupport::Concern
26
+ #
27
+ # included do
28
+ # scope :disabled, where(:disabled => true)
29
+ # end
30
+ #
31
+ # module ClassMethods
32
+ # ...
33
+ # end
34
+ #
35
+ # module InstanceMethods
36
+ # ...
37
+ # end
38
+ # end
39
+ #
40
+ # Moreover, it gracefully handles module dependencies. Given a +Foo+ module and a +Bar+
41
+ # module which depends on the former, we would typically write the following:
42
+ #
43
+ # module Foo
44
+ # def self.included(base)
45
+ # base.class_eval do
46
+ # def self.method_injected_by_foo
47
+ # ...
48
+ # end
49
+ # end
50
+ # end
51
+ # end
52
+ #
53
+ # module Bar
54
+ # def self.included(base)
55
+ # base.method_injected_by_foo
56
+ # end
57
+ # end
58
+ #
59
+ # class Host
60
+ # include Foo # We need to include this dependency for Bar
61
+ # include Bar # Bar is the module that Host really needs
62
+ # end
63
+ #
64
+ # But why should +Host+ care about +Bar+'s dependencies, namely +Foo+? We could try to hide
65
+ # these from +Host+ directly including +Foo+ in +Bar+:
66
+ #
67
+ # module Bar
68
+ # include Foo
69
+ # def self.included(base)
70
+ # base.method_injected_by_foo
71
+ # end
72
+ # end
73
+ #
74
+ # class Host
75
+ # include Bar
76
+ # end
77
+ #
78
+ # Unfortunately this won't work, since when +Foo+ is included, its <tt>base</tt> is the +Bar+ module,
79
+ # not the +Host+ class. With <tt>ActiveSupport::Concern</tt>, module dependencies are properly resolved:
80
+ #
81
+ # require 'active_support/concern'
82
+ #
83
+ # module Foo
84
+ # extend ActiveSupport::Concern
85
+ # included do
86
+ # class_eval do
87
+ # def self.method_injected_by_foo
88
+ # ...
89
+ # end
90
+ # end
91
+ # end
92
+ # end
93
+ #
94
+ # module Bar
95
+ # extend ActiveSupport::Concern
96
+ # include Foo
97
+ #
98
+ # included do
99
+ # self.method_injected_by_foo
100
+ # end
101
+ # end
102
+ #
103
+ # class Host
104
+ # include Bar # works, Bar takes care now of its dependencies
105
+ # end
106
+ #
37
107
  module Concern
38
108
  def self.extended(base)
39
109
  base.instance_variable_set("@_dependencies", [])
@@ -2,14 +2,37 @@ require 'active_support/concern'
2
2
  require 'active_support/ordered_options'
3
3
  require 'active_support/core_ext/kernel/singleton_class'
4
4
  require 'active_support/core_ext/module/delegation'
5
+ require 'active_support/core_ext/array/extract_options'
5
6
 
6
7
  module ActiveSupport
8
+ # Configurable provides a <tt>config</tt> method to store and retrieve
9
+ # configuration options as an <tt>OrderedHash</tt>.
7
10
  module Configurable
8
11
  extend ActiveSupport::Concern
9
12
 
13
+ class Configuration < ActiveSupport::InheritableOptions
14
+ def compile_methods!
15
+ self.class.compile_methods!(keys)
16
+ end
17
+
18
+ # compiles reader methods so we don't have to go through method_missing
19
+ def self.compile_methods!(keys)
20
+ keys.reject { |m| method_defined?(m) }.each do |key|
21
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
22
+ def #{key}; _get(#{key.inspect}); end
23
+ RUBY
24
+ end
25
+ end
26
+ end
27
+
10
28
  module ClassMethods
11
29
  def config
12
- @_config ||= ActiveSupport::InheritableOptions.new(superclass.respond_to?(:config) ? superclass.config : {})
30
+ @_config ||= if respond_to?(:superclass) && superclass.respond_to?(:config)
31
+ superclass.config.inheritable_copy
32
+ else
33
+ # create a new "anonymous" class that will host the compiled reader methods
34
+ Class.new(Configuration).new
35
+ end
13
36
  end
14
37
 
15
38
  def configure
@@ -29,20 +52,39 @@ module ActiveSupport
29
52
  # user.allowed_access # => true
30
53
  #
31
54
  def config_accessor(*names)
55
+ options = names.extract_options!
56
+
32
57
  names.each do |name|
33
- code, line = <<-RUBY, __LINE__ + 1
34
- def #{name}; config.#{name}; end
35
- def #{name}=(value); config.#{name} = value; end
36
- RUBY
58
+ reader, line = "def #{name}; config.#{name}; end", __LINE__
59
+ writer, line = "def #{name}=(value); config.#{name} = value; end", __LINE__
37
60
 
38
- singleton_class.class_eval code, __FILE__, line
39
- class_eval code, __FILE__, line
61
+ singleton_class.class_eval reader, __FILE__, line
62
+ singleton_class.class_eval writer, __FILE__, line
63
+ class_eval reader, __FILE__, line unless options[:instance_reader] == false
64
+ class_eval writer, __FILE__, line unless options[:instance_writer] == false
40
65
  end
41
66
  end
42
67
  end
43
68
 
69
+ # Reads and writes attributes from a configuration <tt>OrderedHash</tt>.
70
+ #
71
+ # require 'active_support/configurable'
72
+ #
73
+ # class User
74
+ # include ActiveSupport::Configurable
75
+ # end
76
+ #
77
+ # user = User.new
78
+ #
79
+ # user.config.allowed_access = true
80
+ # user.config.level = 1
81
+ #
82
+ # user.config.allowed_access # => true
83
+ # user.config.level # => 1
84
+ #
44
85
  def config
45
- @_config ||= ActiveSupport::InheritableOptions.new(self.class.config)
86
+ @_config ||= self.class.config.inheritable_copy
46
87
  end
47
88
  end
48
89
  end
90
+
@@ -3,10 +3,10 @@ class Array
3
3
  #
4
4
  # %w( a b c d ).from(0) # => %w( a b c d )
5
5
  # %w( a b c d ).from(2) # => %w( c d )
6
- # %w( a b c d ).from(10) # => nil
6
+ # %w( a b c d ).from(10) # => %w()
7
7
  # %w().from(0) # => %w()
8
8
  def from(position)
9
- self[position..-1]
9
+ self[position, length] || []
10
10
  end
11
11
 
12
12
  # Returns the beginning of the array up to +position+.
@@ -37,12 +37,12 @@ class Array
37
37
  # Converts a collection of elements into a formatted string by calling
38
38
  # <tt>to_s</tt> on all elements and joining them:
39
39
  #
40
- # Blog.find(:all).to_formatted_s # => "First PostSecond PostThird Post"
40
+ # Blog.all.to_formatted_s # => "First PostSecond PostThird Post"
41
41
  #
42
42
  # Adding in the <tt>:db</tt> argument as the format yields a prettier
43
43
  # output:
44
44
  #
45
- # Blog.find(:all).to_formatted_s(:db) # => "First Post,Second Post,Third Post"
45
+ # Blog.all.to_formatted_s(:db) # => "First Post,Second Post,Third Post"
46
46
  def to_formatted_s(format = :default)
47
47
  case format
48
48
  when :db
@@ -1,12 +1,15 @@
1
1
  class Array
2
- # Backport of Array#sample based on Marc-Andre Lafortune's http://github.com/marcandre/backports/
2
+ # Backport of Array#sample based on Marc-Andre Lafortune's https://github.com/marcandre/backports/
3
3
  # Returns a random element or +n+ random elements from the array.
4
- # If the array is empty and +n+ is nil, returns <tt>nil</tt>. if +n+ is passed, returns <tt>[]</tt>.
4
+ # If the array is empty and +n+ is nil, returns <tt>nil</tt>.
5
+ # If +n+ is passed and its value is less than 0, it raises an +ArgumentError+ exception.
6
+ # If the value of +n+ is equal or greater than 0 it returns <tt>[]</tt>.
5
7
  #
6
- # [1,2,3,4,5,6].sample # => 4
7
- # [1,2,3,4,5,6].sample(3) # => [2, 4, 5]
8
- # [].sample # => nil
9
- # [].sample(3) # => []
8
+ # [1,2,3,4,5,6].sample # => 4
9
+ # [1,2,3,4,5,6].sample(3) # => [2, 4, 5]
10
+ # [1,2,3,4,5,6].sample(-3) # => ArgumentError: negative array size
11
+ # [].sample # => nil
12
+ # [].sample(3) # => []
10
13
  def sample(n=nil)
11
14
  return self[Kernel.rand(size)] if n.nil?
12
15
  n = n.to_int
@@ -24,4 +27,4 @@ class Array
24
27
  result[n..size] = []
25
28
  result
26
29
  end unless method_defined? :sample
27
- end
30
+ end
@@ -1,8 +1,7 @@
1
1
  class Array
2
- # Return an unique array based on the criteria given as a proc.
2
+ # Returns an unique array based on the criteria given as a +Proc+.
3
3
  #
4
- # [1, 2, 3, 4].uniq_by { |i| i.odd? }
5
- # # => [1, 2]
4
+ # [1, 2, 3, 4].uniq_by { |i| i.odd? } # => [1, 2]
6
5
  #
7
6
  def uniq_by
8
7
  hash, array = {}, []
@@ -14,7 +14,7 @@ class Array
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>Arraw.wrap</tt> returns
17
+ # moves on to try +to_a+ if the returned value is +nil+, but <tt>Array.wrap</tt> returns
18
18
  # such a +nil+ right away.
19
19
  # * If the returned value from +to_ary+ is neither +nil+ nor an +Array+ object, <tt>Kernel#Array</tt>
20
20
  # raises an exception, while <tt>Array.wrap</tt> does not, it just returns the value.
@@ -11,8 +11,6 @@ class BigDecimal
11
11
  YAML_TAG = 'tag:yaml.org,2002:float'
12
12
  YAML_MAPPING = { 'Infinity' => '.Inf', '-Infinity' => '-.Inf', 'NaN' => '.NaN' }
13
13
 
14
- yaml_as YAML_TAG
15
-
16
14
  # This emits the number without any scientific notation.
17
15
  # This is better than self.to_f.to_s since it doesn't lose precision.
18
16
  #
@@ -80,13 +80,22 @@ class Class
80
80
  remove_possible_method(:#{name})
81
81
  define_method(:#{name}) { val }
82
82
  end
83
+
84
+ if singleton_class?
85
+ class_eval do
86
+ remove_possible_method(:#{name})
87
+ def #{name}
88
+ defined?(@#{name}) ? @#{name} : singleton_class.#{name}
89
+ end
90
+ end
91
+ end
83
92
  val
84
93
  end
85
94
 
86
95
  if instance_reader
87
96
  remove_possible_method :#{name}
88
97
  def #{name}
89
- defined?(@#{name}) ? @#{name} : singleton_class.#{name}
98
+ defined?(@#{name}) ? @#{name} : self.class.#{name}
90
99
  end
91
100
 
92
101
  def #{name}?
@@ -98,4 +107,9 @@ class Class
98
107
  attr_writer name if instance_writer
99
108
  end
100
109
  end
110
+
111
+ private
112
+ def singleton_class?
113
+ !name || '' == name
114
+ end
101
115
  end
@@ -1,8 +1,10 @@
1
1
  require 'active_support/core_ext/object/duplicable'
2
2
  require 'active_support/core_ext/array/extract_options'
3
+ require 'active_support/deprecation'
3
4
 
4
5
  # Retained for backward compatibility. Methods are now included in Class.
5
6
  module ClassInheritableAttributes # :nodoc:
7
+ DEPRECATION_WARNING_MESSAGE = "class_inheritable_attribute is deprecated, please use class_attribute method instead. Notice their behavior are slightly different, so refer to class_attribute documentation first"
6
8
  end
7
9
 
8
10
  # It is recommended to use <tt>class_attribute</tt> over methods defined in this file. Please
@@ -36,6 +38,7 @@ end
36
38
  # Person.new.hair_colors # => NoMethodError
37
39
  class Class # :nodoc:
38
40
  def class_inheritable_reader(*syms)
41
+ ActiveSupport::Deprecation.warn ClassInheritableAttributes::DEPRECATION_WARNING_MESSAGE
39
42
  options = syms.extract_options!
40
43
  syms.each do |sym|
41
44
  next if sym.is_a?(Hash)
@@ -54,6 +57,7 @@ class Class # :nodoc:
54
57
  end
55
58
 
56
59
  def class_inheritable_writer(*syms)
60
+ ActiveSupport::Deprecation.warn ClassInheritableAttributes::DEPRECATION_WARNING_MESSAGE
57
61
  options = syms.extract_options!
58
62
  syms.each do |sym|
59
63
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
@@ -71,6 +75,7 @@ class Class # :nodoc:
71
75
  end
72
76
 
73
77
  def class_inheritable_array_writer(*syms)
78
+ ActiveSupport::Deprecation.warn ClassInheritableAttributes::DEPRECATION_WARNING_MESSAGE
74
79
  options = syms.extract_options!
75
80
  syms.each do |sym|
76
81
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
@@ -88,6 +93,7 @@ class Class # :nodoc:
88
93
  end
89
94
 
90
95
  def class_inheritable_hash_writer(*syms)
96
+ ActiveSupport::Deprecation.warn ClassInheritableAttributes::DEPRECATION_WARNING_MESSAGE
91
97
  options = syms.extract_options!
92
98
  syms.each do |sym|
93
99
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
@@ -145,6 +151,7 @@ class Class # :nodoc:
145
151
  end
146
152
 
147
153
  def reset_inheritable_attributes
154
+ ActiveSupport::Deprecation.warn ClassInheritableAttributes::DEPRECATION_WARNING_MESSAGE
148
155
  @inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
149
156
  end
150
157
 
@@ -158,9 +165,9 @@ class Class # :nodoc:
158
165
  if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
159
166
  new_inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
160
167
  else
161
- new_inheritable_attributes = inheritable_attributes.inject({}) do |memo, (key, value)|
162
- memo.update(key => value.duplicable? ? value.dup : value)
163
- end
168
+ new_inheritable_attributes = Hash[inheritable_attributes.map do |(key, value)|
169
+ [key, value.duplicable? ? value.dup : value]
170
+ end]
164
171
  end
165
172
 
166
173
  child.instance_variable_set('@inheritable_attributes', new_inheritable_attributes)
@@ -169,86 +176,3 @@ class Class # :nodoc:
169
176
  alias inherited_without_inheritable_attributes inherited
170
177
  alias inherited inherited_with_inheritable_attributes
171
178
  end
172
-
173
- class Class
174
- # Defines class-level inheritable attribute reader. Attributes are available to subclasses,
175
- # each subclass has a copy of parent's attribute.
176
- #
177
- # @param *syms<Array[#to_s]> Array of attributes to define inheritable reader for.
178
- # @return <Array[#to_s]> Array of attributes converted into inheritable_readers.
179
- #
180
- # @api public
181
- #
182
- # @todo Do we want to block instance_reader via :instance_reader => false
183
- # @todo It would be preferable that we do something with a Hash passed in
184
- # (error out or do the same as other methods above) instead of silently
185
- # moving on). In particular, this makes the return value of this function
186
- # less useful.
187
- def extlib_inheritable_reader(*ivars, &block)
188
- options = ivars.extract_options!
189
-
190
- ivars.each do |ivar|
191
- self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
192
- def self.#{ivar}
193
- return @#{ivar} if self.object_id == #{self.object_id} || defined?(@#{ivar})
194
- ivar = superclass.#{ivar}
195
- return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
196
- @#{ivar} = ivar.duplicable? ? ivar.dup : ivar
197
- end
198
- RUBY
199
- unless options[:instance_reader] == false
200
- self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
201
- def #{ivar}
202
- self.class.#{ivar}
203
- end
204
- RUBY
205
- end
206
- instance_variable_set(:"@#{ivar}", yield) if block_given?
207
- end
208
- end
209
-
210
- # Defines class-level inheritable attribute writer. Attributes are available to subclasses,
211
- # each subclass has a copy of parent's attribute.
212
- #
213
- # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
214
- # define inheritable writer for.
215
- # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
216
- # @return <Array[#to_s]> An Array of the attributes that were made into inheritable writers.
217
- #
218
- # @api public
219
- #
220
- # @todo We need a style for class_eval <<-HEREDOC. I'd like to make it
221
- # class_eval(<<-RUBY, __FILE__, __LINE__), but we should codify it somewhere.
222
- def extlib_inheritable_writer(*ivars)
223
- options = ivars.extract_options!
224
-
225
- ivars.each do |ivar|
226
- self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
227
- def self.#{ivar}=(obj)
228
- @#{ivar} = obj
229
- end
230
- RUBY
231
- unless options[:instance_writer] == false
232
- self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
233
- def #{ivar}=(obj) self.class.#{ivar} = obj end
234
- RUBY
235
- end
236
-
237
- self.send("#{ivar}=", yield) if block_given?
238
- end
239
- end
240
-
241
- # Defines class-level inheritable attribute accessor. Attributes are available to subclasses,
242
- # each subclass has a copy of parent's attribute.
243
- #
244
- # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
245
- # define inheritable accessor for.
246
- # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
247
- # @return <Array[#to_s]> An Array of attributes turned into inheritable accessors.
248
- #
249
- # @api public
250
- def extlib_inheritable_accessor(*syms, &block)
251
- extlib_inheritable_reader(*syms)
252
- extlib_inheritable_writer(*syms, &block)
253
- end
254
- end
@@ -2,49 +2,35 @@ require 'active_support/core_ext/module/anonymous'
2
2
  require 'active_support/core_ext/module/reachable'
3
3
 
4
4
  class Class #:nodoc:
5
- # Rubinius
6
- if defined?(Class.__subclasses__)
7
- alias :subclasses :__subclasses__
5
+ begin
6
+ ObjectSpace.each_object(Class.new) {}
8
7
 
9
8
  def descendants
10
9
  descendants = []
11
- __subclasses__.each do |k|
12
- descendants << k
13
- descendants.concat k.descendants
10
+ ObjectSpace.each_object(class << self; self; end) do |k|
11
+ descendants.unshift k unless k == self
14
12
  end
15
13
  descendants
16
14
  end
17
- else # MRI
18
- begin
19
- ObjectSpace.each_object(Class.new) {}
20
-
21
- def descendants
22
- descendants = []
23
- ObjectSpace.each_object(class << self; self; end) do |k|
24
- descendants.unshift k unless k == self
25
- end
26
- descendants
27
- end
28
- rescue StandardError # JRuby
29
- def descendants
30
- descendants = []
31
- ObjectSpace.each_object(Class) do |k|
32
- descendants.unshift k if k < self
33
- end
34
- descendants.uniq!
35
- descendants
15
+ rescue StandardError # JRuby
16
+ def descendants
17
+ descendants = []
18
+ ObjectSpace.each_object(Class) do |k|
19
+ descendants.unshift k if k < self
36
20
  end
21
+ descendants.uniq!
22
+ descendants
37
23
  end
24
+ end
38
25
 
39
- # Returns an array with the direct children of +self+.
40
- #
41
- # Integer.subclasses # => [Bignum, Fixnum]
42
- def subclasses
43
- subclasses, chain = [], descendants
44
- chain.each do |k|
45
- subclasses << k unless chain.any? { |c| c > k }
46
- end
47
- subclasses
26
+ # Returns an array with the direct children of +self+.
27
+ #
28
+ # Integer.subclasses # => [Bignum, Fixnum]
29
+ def subclasses
30
+ subclasses, chain = [], descendants
31
+ chain.each do |k|
32
+ subclasses << k unless chain.any? { |c| c > k }
48
33
  end
34
+ subclasses
49
35
  end
50
36
  end
@@ -5,6 +5,8 @@ require 'active_support/core_ext/date/zones'
5
5
  require 'active_support/core_ext/time/zones'
6
6
 
7
7
  class Date
8
+ DAYS_INTO_WEEK = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6 }
9
+
8
10
  if RUBY_VERSION < '1.9'
9
11
  undef :>>
10
12
 
@@ -127,6 +129,11 @@ class Date
127
129
  )
128
130
  end
129
131
 
132
+ # Returns a new Date/DateTime representing the time a number of specified weeks ago.
133
+ def weeks_ago(weeks)
134
+ advance(:weeks => -weeks)
135
+ end
136
+
130
137
  # Returns a new Date/DateTime representing the time a number of specified months ago.
131
138
  def months_ago(months)
132
139
  advance(:months => -months)
@@ -185,16 +192,21 @@ class Date
185
192
  alias :sunday :end_of_week
186
193
  alias :at_end_of_week :end_of_week
187
194
 
195
+ # Returns a new Date/DateTime representing the start of the given day in the previous week (default is Monday).
196
+ def prev_week(day = :monday)
197
+ result = (self - 7).beginning_of_week + DAYS_INTO_WEEK[day]
198
+ self.acts_like?(:time) ? result.change(:hour => 0) : result
199
+ end
200
+
188
201
  # Returns a new Date/DateTime representing the start of the given day in next week (default is Monday).
189
202
  def next_week(day = :monday)
190
- days_into_week = { :monday => 0, :tuesday => 1, :wednesday => 2, :thursday => 3, :friday => 4, :saturday => 5, :sunday => 6}
191
- result = (self + 7).beginning_of_week + days_into_week[day]
203
+ result = (self + 7).beginning_of_week + DAYS_INTO_WEEK[day]
192
204
  self.acts_like?(:time) ? result.change(:hour => 0) : result
193
205
  end
194
206
 
195
207
  # Returns a new ; DateTime objects will have time set to 0:00DateTime representing the start of the month (1st of the month; DateTime objects will have time set to 0:00)
196
208
  def beginning_of_month
197
- self.acts_like?(:time) ? change(:day => 1,:hour => 0, :min => 0, :sec => 0) : change(:day => 1)
209
+ self.acts_like?(:time) ? change(:day => 1, :hour => 0) : change(:day => 1)
198
210
  end
199
211
  alias :at_beginning_of_month :beginning_of_month
200
212
 
@@ -219,13 +231,13 @@ class Date
219
231
 
220
232
  # Returns a new Date/DateTime representing the start of the year (1st of january; DateTime objects will have time set to 0:00)
221
233
  def beginning_of_year
222
- self.acts_like?(:time) ? change(:month => 1, :day => 1, :hour => 0, :min => 0, :sec => 0) : change(:month => 1, :day => 1)
234
+ self.acts_like?(:time) ? change(:month => 1, :day => 1, :hour => 0) : change(:month => 1, :day => 1)
223
235
  end
224
236
  alias :at_beginning_of_year :beginning_of_year
225
237
 
226
238
  # Returns a new Time representing the end of the year (31st of december; DateTime objects will have time set to 23:59:59)
227
239
  def end_of_year
228
- self.acts_like?(:time) ? change(:month => 12,:day => 31,:hour => 23, :min => 59, :sec => 59) : change(:month => 12, :day => 31)
240
+ self.acts_like?(:time) ? change(:month => 12, :day => 31, :hour => 23, :min => 59, :sec => 59) : change(:month => 12, :day => 31)
229
241
  end
230
242
  alias :at_end_of_year :end_of_year
231
243
 
@@ -1,6 +1,7 @@
1
1
  require 'date'
2
2
  require 'active_support/inflector/methods'
3
3
  require 'active_support/core_ext/date/zones'
4
+ require 'active_support/core_ext/module/remove_method'
4
5
 
5
6
  class Date
6
7
  DATE_FORMATS = {
@@ -13,10 +14,10 @@ class Date
13
14
  }
14
15
 
15
16
  # Ruby 1.9 has Date#to_time which converts to localtime only.
16
- remove_method :to_time if method_defined?(:to_time)
17
+ remove_possible_method :to_time
17
18
 
18
19
  # Ruby 1.9 has Date#xmlschema which converts to a string without the time component.
19
- remove_method :xmlschema if method_defined?(:xmlschema)
20
+ remove_possible_method :xmlschema
20
21
 
21
22
  # Convert to a formatted string. See DATE_FORMATS for predefined formats.
22
23
  #
@@ -93,6 +94,12 @@ class Date
93
94
  ::DateTime.civil(year, month, day, 0, 0, 0, 0)
94
95
  end if RUBY_VERSION < '1.9'
95
96
 
97
+ def iso8601
98
+ strftime('%F')
99
+ end if RUBY_VERSION < '1.9'
100
+
101
+ alias_method :rfc3339, :iso8601 if RUBY_VERSION < '1.9'
102
+
96
103
  def xmlschema
97
104
  to_time_in_current_zone.xmlschema
98
105
  end