activesupport 3.1.0.beta1 → 3.1.0.rc1

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 (46) hide show
  1. data/CHANGELOG +33 -1
  2. data/README.rdoc +1 -1
  3. data/lib/active_support.rb +1 -1
  4. data/lib/active_support/buffered_logger.rb +9 -4
  5. data/lib/active_support/configurable.rb +9 -6
  6. data/lib/active_support/core_ext/array/conversions.rb +2 -2
  7. data/lib/active_support/core_ext/array/random_access.rb +1 -1
  8. data/lib/active_support/core_ext/array/uniq_by.rb +2 -3
  9. data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -2
  10. data/lib/active_support/core_ext/date/calculations.rb +3 -3
  11. data/lib/active_support/core_ext/date/conversions.rb +3 -2
  12. data/lib/active_support/core_ext/date_time/conversions.rb +8 -8
  13. data/lib/active_support/core_ext/hash/conversions.rb +2 -1
  14. data/lib/active_support/core_ext/hash/indifferent_access.rb +12 -0
  15. data/lib/active_support/core_ext/hash/slice.rb +1 -1
  16. data/lib/active_support/core_ext/integer/inflections.rb +7 -4
  17. data/lib/active_support/core_ext/kernel/reporting.rb +13 -1
  18. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +1 -0
  19. data/lib/active_support/core_ext/module/deprecation.rb +0 -2
  20. data/lib/active_support/core_ext/numeric/time.rb +2 -0
  21. data/lib/active_support/core_ext/object/blank.rb +3 -3
  22. data/lib/active_support/core_ext/object/duplicable.rb +2 -0
  23. data/lib/active_support/core_ext/object/try.rb +2 -0
  24. data/lib/active_support/core_ext/object/with_options.rb +8 -5
  25. data/lib/active_support/core_ext/string/behavior.rb +1 -2
  26. data/lib/active_support/core_ext/string/exclude.rb +1 -1
  27. data/lib/active_support/core_ext/string/inquiry.rb +1 -1
  28. data/lib/active_support/core_ext/time/calculations.rb +4 -3
  29. data/lib/active_support/core_ext/time/marshal.rb +1 -0
  30. data/lib/active_support/descendants_tracker.rb +9 -7
  31. data/lib/active_support/duration.rb +1 -0
  32. data/lib/active_support/hash_with_indifferent_access.rb +12 -4
  33. data/lib/active_support/inflector/methods.rb +5 -3
  34. data/lib/active_support/json/encoding.rb +4 -1
  35. data/lib/active_support/log_subscriber/test_helper.rb +1 -0
  36. data/lib/active_support/ordered_hash.rb +4 -0
  37. data/lib/active_support/secure_random.rb +3 -202
  38. data/lib/active_support/testing/performance.rb +227 -335
  39. data/lib/active_support/testing/performance/jruby.rb +115 -0
  40. data/lib/active_support/testing/performance/rubinius.rb +113 -0
  41. data/lib/active_support/testing/performance/ruby.rb +152 -0
  42. data/lib/active_support/testing/performance/ruby/mri.rb +59 -0
  43. data/lib/active_support/testing/performance/ruby/yarv.rb +57 -0
  44. data/lib/active_support/version.rb +1 -1
  45. data/lib/active_support/xml_mini.rb +4 -1
  46. metadata +8 -3
data/CHANGELOG CHANGED
@@ -1,5 +1,7 @@
1
1
  *Rails 3.1.0 (unreleased)*
2
2
 
3
+ * New reporting method Kernel#quietly. [fxn]
4
+
3
5
  * Add String#inquiry as a convenience method for turning a string into a StringInquirer object [DHH]
4
6
 
5
7
  * Add Object#in? to test if an object is included in another object [Prem Sichanugrist, Brian Morearty, John Reitano]
@@ -19,14 +21,44 @@ advantage of the new ClassCache.
19
21
 
20
22
  * Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]
21
23
 
22
- *Rails 3.0.2 (unreleased)*
24
+ * JSON decoding now uses the multi_json gem which also vendors a json engine called OkJson. The yaml backend has been removed in favor of OkJson as a default engine for 1.8.x, while the built in 1.9.x json implementation will be used by default. [Josh Kalderimis]
25
+
26
+
27
+ *Rails 3.0.7 (April 18, 2011)*
28
+
29
+ * Hash.from_xml no longer loses attributes on tags containing only whitespace [André Arko]
30
+
31
+
32
+ *Rails 3.0.6 (April 5, 2011)
33
+
34
+ * No changes.
35
+
36
+
37
+ *Rails 3.0.5 (February 26, 2011)*
38
+
39
+ * No changes.
40
+
41
+
42
+ *Rails 3.0.4 (February 8, 2011)*
43
+
44
+ * No changes.
45
+
46
+
47
+ *Rails 3.0.3 (November 16, 2010)*
48
+
49
+ * No changes.
50
+
51
+
52
+ *Rails 3.0.2 (November 15, 2010)*
23
53
 
24
54
  * Added before_remove_const callback to ActiveSupport::Dependencies.remove_unloadable_constants! [Andrew White]
25
55
 
56
+
26
57
  *Rails 3.0.1 (October 15, 2010)*
27
58
 
28
59
  * No Changes, just a version bump.
29
60
 
61
+
30
62
  *Rails 3.0.0 (August 29, 2010)*
31
63
 
32
64
  * Implemented String#strip_heredoc. [fxn]
@@ -30,4 +30,4 @@ API documentation is at
30
30
 
31
31
  Bug reports and feature requests can be filed with the rest for the Ruby on Rails project here:
32
32
 
33
- * https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets
33
+ * https://github.com/rails/rails/issues
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright (c) 2005 David Heinemeier Hansson
2
+ # Copyright (c) 2005-2011 David Heinemeier Hansson
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -48,12 +48,17 @@ module ActiveSupport
48
48
  if log.respond_to?(:write)
49
49
  @log = log
50
50
  elsif File.exist?(log)
51
- @log = open(log, (File::WRONLY | File::APPEND))
52
- @log.sync = true
51
+ @log = open_log(log, (File::WRONLY | File::APPEND))
53
52
  else
54
53
  FileUtils.mkdir_p(File.dirname(log))
55
- @log = open(log, (File::WRONLY | File::APPEND | File::CREAT))
56
- @log.sync = true
54
+ @log = open_log(log, (File::WRONLY | File::APPEND | File::CREAT))
55
+ end
56
+ end
57
+
58
+ def open_log(log, mode)
59
+ open(log, mode).tap do |open_log|
60
+ open_log.set_encoding(Encoding::BINARY) if open_log.respond_to?(:set_encoding)
61
+ open_log.sync = true
57
62
  end
58
63
  end
59
64
 
@@ -2,6 +2,7 @@ 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
7
8
  # Configurable provides a <tt>config</tt> method to store and retrieve
@@ -51,14 +52,16 @@ module ActiveSupport
51
52
  # user.allowed_access # => true
52
53
  #
53
54
  def config_accessor(*names)
55
+ options = names.extract_options!
56
+
54
57
  names.each do |name|
55
- code, line = <<-RUBY, __LINE__ + 1
56
- def #{name}; config.#{name}; end
57
- def #{name}=(value); config.#{name} = value; end
58
- RUBY
58
+ reader, line = "def #{name}; config.#{name}; end", __LINE__
59
+ writer, line = "def #{name}=(value); config.#{name} = value; end", __LINE__
59
60
 
60
- singleton_class.class_eval code, __FILE__, line
61
- 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
62
65
  end
63
66
  end
64
67
  end
@@ -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
@@ -7,7 +7,7 @@ class Array
7
7
  #
8
8
  # [1,2,3,4,5,6].sample # => 4
9
9
  # [1,2,3,4,5,6].sample(3) # => [2, 4, 5]
10
- # [1,2,3,4,5,6].sample(-3) # => ArgumentError: negative sample number
10
+ # [1,2,3,4,5,6].sample(-3) # => ArgumentError: negative array size
11
11
  # [].sample # => nil
12
12
  # [].sample(3) # => []
13
13
  def sample(n=nil)
@@ -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 = {}, []
@@ -130,7 +130,6 @@ class Class # :nodoc:
130
130
  end
131
131
 
132
132
  def write_inheritable_attribute(key, value)
133
- ActiveSupport::Deprecation.warn ClassInheritableAttributes::DEPRECATION_WARNING_MESSAGE
134
133
  if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
135
134
  @inheritable_attributes = {}
136
135
  end
@@ -148,7 +147,6 @@ class Class # :nodoc:
148
147
  end
149
148
 
150
149
  def read_inheritable_attribute(key)
151
- ActiveSupport::Deprecation.warn ClassInheritableAttributes::DEPRECATION_WARNING_MESSAGE
152
150
  inheritable_attributes[key]
153
151
  end
154
152
 
@@ -206,7 +206,7 @@ class Date
206
206
 
207
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)
208
208
  def beginning_of_month
209
- 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)
210
210
  end
211
211
  alias :at_beginning_of_month :beginning_of_month
212
212
 
@@ -231,13 +231,13 @@ class Date
231
231
 
232
232
  # Returns a new Date/DateTime representing the start of the year (1st of january; DateTime objects will have time set to 0:00)
233
233
  def beginning_of_year
234
- 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)
235
235
  end
236
236
  alias :at_beginning_of_year :beginning_of_year
237
237
 
238
238
  # Returns a new Time representing the end of the year (31st of december; DateTime objects will have time set to 23:59:59)
239
239
  def end_of_year
240
- 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)
241
241
  end
242
242
  alias :at_end_of_year :end_of_year
243
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
  #
@@ -51,25 +51,25 @@ class DateTime
51
51
  utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
52
52
  end
53
53
 
54
- # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000"
54
+ # Overrides the default inspect method with a human readable one, e.g., "Mon, 21 Feb 2005 14:30:00 +0000".
55
55
  def readable_inspect
56
56
  to_s(:rfc822)
57
57
  end
58
58
  alias_method :default_inspect, :inspect
59
59
  alias_method :inspect, :readable_inspect
60
60
 
61
- # Converts self to a Ruby Date object; time portion is discarded
61
+ # Converts self to a Ruby Date object; time portion is discarded.
62
62
  def to_date
63
63
  ::Date.new(year, month, day)
64
64
  end unless instance_methods(false).include?(:to_date)
65
65
 
66
- # Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class
67
- # If self has an offset other than 0, self will just be returned unaltered, since there's no clean way to map it to a Time
66
+ # Attempts to convert self to a Ruby Time object; returns self if out of range of Ruby Time class.
67
+ # If self has an offset other than 0, self will just be returned unaltered, since there's no clean way to map it to a Time.
68
68
  def to_time
69
69
  self.offset == 0 ? ::Time.utc_time(year, month, day, hour, min, sec, sec_fraction * (RUBY_VERSION < '1.9' ? 86400000000 : 1000000)) : self
70
70
  end
71
71
 
72
- # To be able to keep Times, Dates and DateTimes interchangeable on conversions
72
+ # To be able to keep Times, Dates and DateTimes interchangeable on conversions.
73
73
  def to_datetime
74
74
  self
75
75
  end unless instance_methods(false).include?(:to_datetime)
@@ -79,17 +79,17 @@ class DateTime
79
79
  civil(year, month, day, hour, min, sec, offset)
80
80
  end
81
81
 
82
- # Converts datetime to an appropriate format for use in XML
82
+ # Converts datetime to an appropriate format for use in XML.
83
83
  def xmlschema
84
84
  strftime("%Y-%m-%dT%H:%M:%S%Z")
85
85
  end unless instance_methods(false).include?(:xmlschema)
86
86
 
87
- # Converts self to a floating-point number of seconds since the Unix epoch
87
+ # Converts self to a floating-point number of seconds since the Unix epoch.
88
88
  def to_f
89
89
  seconds_since_unix_epoch.to_f
90
90
  end
91
91
 
92
- # Converts self to an integer number of seconds since the Unix epoch
92
+ # Converts self to an integer number of seconds since the Unix epoch.
93
93
  def to_i
94
94
  seconds_since_unix_epoch.to_i
95
95
  end
@@ -108,7 +108,8 @@ class Hash
108
108
  raise "can't typecast #{entries.inspect}"
109
109
  end
110
110
  end
111
- elsif value['type'] == 'file' || value["__content__"].present?
111
+ elsif value['type'] == 'file' ||
112
+ (value["__content__"] && (value.keys.size == 1 || value["__content__"].present?))
112
113
  content = value["__content__"]
113
114
  if parser = ActiveSupport::XmlMini::PARSING[value["type"]]
114
115
  parser.arity == 1 ? parser.call(content) : parser.call(content, value)
@@ -9,4 +9,16 @@ class Hash
9
9
  def with_indifferent_access
10
10
  ActiveSupport::HashWithIndifferentAccess.new_from_hash_copying_default(self)
11
11
  end
12
+
13
+ # Called when object is nested under an object that receives
14
+ # #with_indifferent_access. This method with be called on the current object
15
+ # by the enclosing object and is aliased to #with_indifferent_access by
16
+ # default. Subclasses of Hash may overwrite this method to return +self+ if
17
+ # converting to an +ActiveSupport::HashWithIndifferentAccess+ would not be
18
+ # desirable.
19
+ #
20
+ # b = {:b => 1}
21
+ # {:a => b}.with_indifferent_access["a"] # calls b.nested_under_indifferent_access
22
+ #
23
+ alias nested_under_indifferent_access with_indifferent_access
12
24
  end
@@ -21,7 +21,7 @@ class Hash
21
21
 
22
22
  # Replaces the hash with only the given keys.
23
23
  # Returns a hash contained the removed key/value pairs
24
- # {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d =>4}
24
+ # {:a => 1, :b => 2, :c => 3, :d => 4}.slice!(:a, :b) # => {:c => 3, :d => 4}
25
25
  def slice!(*keys)
26
26
  keys = keys.map! { |key| convert_key(key) } if respond_to?(:convert_key)
27
27
  omit = slice(*self.keys - keys)
@@ -4,10 +4,13 @@ class Integer
4
4
  # Ordinalize turns a number into an ordinal string used to denote the
5
5
  # position in an ordered sequence such as 1st, 2nd, 3rd, 4th.
6
6
  #
7
- # 1.ordinalize # => "1st"
8
- # 2.ordinalize # => "2nd"
9
- # 1002.ordinalize # => "1002nd"
10
- # 1003.ordinalize # => "1003rd"
7
+ # 1.ordinalize # => "1st"
8
+ # 2.ordinalize # => "2nd"
9
+ # 1002.ordinalize # => "1002nd"
10
+ # 1003.ordinalize # => "1003rd"
11
+ # -11.ordinalize # => "-11th"
12
+ # -1001.ordinalize # => "-1001st"
13
+ #
11
14
  def ordinalize
12
15
  ActiveSupport::Inflector.ordinalize(self)
13
16
  end
@@ -62,7 +62,7 @@ module Kernel
62
62
 
63
63
  # Captures the given stream and returns it:
64
64
  #
65
- # stream = capture(:stdout){ puts "Cool" }
65
+ # stream = capture(:stdout) { puts "Cool" }
66
66
  # stream # => "Cool\n"
67
67
  #
68
68
  def capture(stream)
@@ -78,4 +78,16 @@ module Kernel
78
78
  result
79
79
  end
80
80
  alias :silence :capture
81
+
82
+ # Silences both STDOUT and STDERR, even for subprocesses.
83
+ #
84
+ # quietly { system 'bundle install' }
85
+ #
86
+ def quietly
87
+ silence_stream(STDOUT) do
88
+ silence_stream(STDERR) do
89
+ yield
90
+ end
91
+ end
92
+ end
81
93
  end
@@ -19,6 +19,7 @@ class Module
19
19
  # attr_accessor_with_default(:element_name) { name.underscore }
20
20
  #
21
21
  def attr_accessor_with_default(sym, default = Proc.new)
22
+ ActiveSupport::Deprecation.warn "attr_accessor_with_default is deprecated. Use Ruby instead!"
22
23
  define_method(sym, block_given? ? default : Proc.new { default })
23
24
  module_eval(<<-EVAL, __FILE__, __LINE__ + 1)
24
25
  def #{sym}=(value) # def age=(value)
@@ -1,5 +1,3 @@
1
- require 'active_support/deprecation'
2
-
3
1
  class Module
4
2
  # Declare that a method has been deprecated.
5
3
  # deprecate :foo
@@ -1,4 +1,6 @@
1
1
  require 'active_support/duration'
2
+ require 'active_support/core_ext/time/calculations'
3
+ require 'active_support/core_ext/time/acts_like'
2
4
 
3
5
  class Numeric
4
6
  # Enables the use of time calculations and declarations, like 45.minutes + 2.hours + 4.years.
@@ -1,14 +1,14 @@
1
1
  class Object
2
2
  # An object is blank if it's false, empty, or a whitespace string.
3
- # For example, "", " ", +nil+, [], and {} are blank.
3
+ # For example, "", " ", +nil+, [], and {} are all blank.
4
4
  #
5
5
  # This simplifies:
6
6
  #
7
- # if !address.nil? && !address.empty?
7
+ # if address.nil? || address.empty?
8
8
  #
9
9
  # ...to:
10
10
  #
11
- # if !address.blank?
11
+ # if address.blank?
12
12
  def blank?
13
13
  respond_to?(:empty?) ? empty? : !self
14
14
  end
@@ -1,3 +1,4 @@
1
+ #--
1
2
  # Most objects are cloneable, but not all. For example you can't dup +nil+:
2
3
  #
3
4
  # nil.dup # => TypeError: can't dup NilClass
@@ -14,6 +15,7 @@
14
15
  #
15
16
  # That's why we hardcode the following cases and check duplicable? instead of
16
17
  # using that rescue idiom.
18
+ #++
17
19
  class Object
18
20
  # Can you safely dup this object?
19
21
  #
@@ -28,6 +28,8 @@ class Object
28
28
  def try(*a, &b)
29
29
  if a.empty? && block_given?
30
30
  yield self
31
+ elsif !a.empty? && !respond_to?(a.first)
32
+ nil
31
33
  else
32
34
  __send__(*a, &b)
33
35
  end
@@ -7,7 +7,7 @@ class Object
7
7
  # provided. Each method called on the block variable must take an options
8
8
  # hash as its final argument.
9
9
  #
10
- # Without with_options, this code contains duplication:
10
+ # Without <tt>with_options></tt>, this code contains duplication:
11
11
  #
12
12
  # class Account < ActiveRecord::Base
13
13
  # has_many :customers, :dependent => :destroy
@@ -16,7 +16,7 @@ class Object
16
16
  # has_many :expenses, :dependent => :destroy
17
17
  # end
18
18
  #
19
- # Using with_options, we can remove the duplication:
19
+ # Using <tt>with_options</tt>, we can remove the duplication:
20
20
  #
21
21
  # class Account < ActiveRecord::Base
22
22
  # with_options :dependent => :destroy do |assoc|
@@ -29,11 +29,14 @@ class Object
29
29
  #
30
30
  # It can also be used with an explicit receiver:
31
31
  #
32
- # map.with_options :controller => "people" do |people|
33
- # people.connect "/people", :action => "index"
34
- # people.connect "/people/:id", :action => "show"
32
+ # I18n.with_options :locale => user.locale, :scope => "newsletter" do |i18n|
33
+ # subject i18n.t :subject
34
+ # body i18n.t :body, :user_name => user.name
35
35
  # end
36
36
  #
37
+ # <tt>with_options</tt> can also be nested since the call is forwarded to its receiver.
38
+ # Each nesting level will merge inherited defaults in addition to their own.
39
+ #
37
40
  def with_options(options)
38
41
  yield ActiveSupport::OptionMerger.new(self, options)
39
42
  end