activesupport 2.2.3 → 2.3.2

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 (94) hide show
  1. data/CHANGELOG +128 -89
  2. data/lib/active_support.rb +31 -33
  3. data/lib/active_support/backtrace_cleaner.rb +72 -0
  4. data/lib/active_support/buffered_logger.rb +9 -7
  5. data/lib/active_support/cache.rb +13 -8
  6. data/lib/active_support/cache/drb_store.rb +2 -3
  7. data/lib/active_support/cache/mem_cache_store.rb +6 -1
  8. data/lib/active_support/cache/strategy/local_cache.rb +104 -0
  9. data/lib/active_support/callbacks.rb +20 -21
  10. data/lib/active_support/core_ext.rb +1 -1
  11. data/lib/active_support/core_ext/array.rb +2 -0
  12. data/lib/active_support/core_ext/array/conversions.rb +26 -13
  13. data/lib/active_support/core_ext/array/wrapper.rb +24 -0
  14. data/lib/active_support/core_ext/benchmark.rb +13 -6
  15. data/lib/active_support/core_ext/cgi/escape_skipping_slashes.rb +14 -5
  16. data/lib/active_support/core_ext/class/attribute_accessors.rb +24 -24
  17. data/lib/active_support/core_ext/class/delegating_attributes.rb +20 -19
  18. data/lib/active_support/core_ext/class/inheritable_attributes.rb +34 -34
  19. data/lib/active_support/core_ext/date/conversions.rb +3 -3
  20. data/lib/active_support/core_ext/date_time/conversions.rb +1 -1
  21. data/lib/active_support/core_ext/enumerable.rb +9 -0
  22. data/lib/active_support/core_ext/exception.rb +12 -8
  23. data/lib/active_support/core_ext/file/atomic.rb +2 -2
  24. data/lib/active_support/core_ext/hash/conversions.rb +32 -54
  25. data/lib/active_support/core_ext/hash/indifferent_access.rb +6 -0
  26. data/lib/active_support/core_ext/hash/keys.rb +1 -1
  27. data/lib/active_support/core_ext/hash/slice.rb +8 -1
  28. data/lib/active_support/core_ext/logger.rb +8 -6
  29. data/lib/active_support/core_ext/module/aliasing.rb +3 -3
  30. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +4 -4
  31. data/lib/active_support/core_ext/module/attribute_accessors.rb +24 -24
  32. data/lib/active_support/core_ext/module/delegation.rb +29 -3
  33. data/lib/active_support/core_ext/module/synchronization.rb +5 -5
  34. data/lib/active_support/core_ext/object/conversions.rb +2 -1
  35. data/lib/active_support/core_ext/object/misc.rb +16 -0
  36. data/lib/active_support/core_ext/range/conversions.rb +1 -1
  37. data/lib/active_support/core_ext/rexml.rb +29 -24
  38. data/lib/active_support/core_ext/string/inflections.rb +3 -3
  39. data/lib/active_support/core_ext/time/calculations.rb +1 -2
  40. data/lib/active_support/core_ext/time/conversions.rb +1 -1
  41. data/lib/active_support/core_ext/try.rb +36 -0
  42. data/lib/active_support/dependencies.rb +18 -14
  43. data/lib/active_support/deprecation.rb +10 -57
  44. data/lib/active_support/duration.rb +3 -1
  45. data/lib/active_support/inflections.rb +1 -0
  46. data/lib/active_support/inflector.rb +16 -7
  47. data/lib/active_support/json/decoding.rb +21 -3
  48. data/lib/active_support/json/encoders/date.rb +1 -1
  49. data/lib/active_support/json/encoders/date_time.rb +1 -1
  50. data/lib/active_support/json/encoders/hash.rb +10 -11
  51. data/lib/active_support/json/encoders/time.rb +1 -1
  52. data/lib/active_support/json/encoding.rb +23 -29
  53. data/lib/active_support/locale/en.yml +3 -2
  54. data/lib/active_support/memoizable.rb +61 -43
  55. data/lib/active_support/message_encryptor.rb +70 -0
  56. data/lib/active_support/message_verifier.rb +46 -0
  57. data/lib/active_support/multibyte.rb +6 -30
  58. data/lib/active_support/multibyte/chars.rb +30 -9
  59. data/lib/active_support/multibyte/unicode_database.rb +4 -4
  60. data/lib/active_support/option_merger.rb +7 -1
  61. data/lib/active_support/ordered_hash.rb +75 -27
  62. data/lib/active_support/secure_random.rb +8 -6
  63. data/lib/active_support/test_case.rb +32 -17
  64. data/lib/active_support/testing/{core_ext/test/unit/assertions.rb → assertions.rb} +13 -20
  65. data/lib/active_support/testing/declarative.rb +21 -0
  66. data/lib/active_support/testing/deprecation.rb +55 -0
  67. data/lib/active_support/testing/performance.rb +1 -1
  68. data/lib/active_support/testing/setup_and_teardown.rb +57 -86
  69. data/lib/active_support/time_with_zone.rb +8 -6
  70. data/lib/active_support/values/time_zone.rb +1 -0
  71. data/lib/active_support/vendor.rb +6 -11
  72. data/lib/active_support/vendor/i18n-0.1.3/MIT-LICENSE +20 -0
  73. data/lib/active_support/vendor/i18n-0.1.3/README.textile +20 -0
  74. data/lib/active_support/vendor/i18n-0.1.3/Rakefile +5 -0
  75. data/lib/active_support/vendor/i18n-0.1.3/i18n.gemspec +27 -0
  76. data/lib/active_support/vendor/{i18n-0.0.1 → i18n-0.1.3/lib}/i18n.rb +42 -37
  77. data/lib/active_support/vendor/{i18n-0.0.1 → i18n-0.1.3/lib}/i18n/backend/simple.rb +37 -39
  78. data/lib/active_support/vendor/{i18n-0.0.1 → i18n-0.1.3/lib}/i18n/exceptions.rb +3 -3
  79. data/lib/active_support/vendor/i18n-0.1.3/test/all.rb +5 -0
  80. data/lib/active_support/vendor/i18n-0.1.3/test/i18n_exceptions_test.rb +100 -0
  81. data/lib/active_support/vendor/i18n-0.1.3/test/i18n_test.rb +125 -0
  82. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.rb +1 -0
  83. data/lib/active_support/vendor/i18n-0.1.3/test/locale/en.yml +3 -0
  84. data/lib/active_support/vendor/i18n-0.1.3/test/simple_backend_test.rb +568 -0
  85. data/lib/active_support/vendor/{memcache-client-1.5.1 → memcache-client-1.6.5}/memcache.rb +381 -295
  86. data/lib/active_support/version.rb +2 -2
  87. data/lib/active_support/xml_mini.rb +31 -0
  88. data/lib/active_support/xml_mini/libxml.rb +133 -0
  89. data/lib/active_support/xml_mini/nokogiri.rb +77 -0
  90. data/lib/active_support/xml_mini/rexml.rb +108 -0
  91. metadata +85 -14
  92. data/lib/active_support/multibyte/utils.rb +0 -61
  93. data/lib/active_support/testing/core_ext/test.rb +0 -6
  94. data/lib/active_support/vendor/xml-simple-1.0.11/xmlsimple.rb +0 -1021
@@ -1,4 +1,4 @@
1
- require 'active_support/inflector'
1
+ require 'active_support/inflector' unless defined?(ActiveSupport::Inflector)
2
2
 
3
3
  module ActiveSupport #:nodoc:
4
4
  module CoreExtensions #:nodoc:
@@ -102,8 +102,8 @@ module ActiveSupport #:nodoc:
102
102
  #
103
103
  # <%= link_to(@person.name, person_path %>
104
104
  # # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
105
- def parameterize
106
- Inflector.parameterize(self)
105
+ def parameterize(sep = '-')
106
+ Inflector.parameterize(self, sep)
107
107
  end
108
108
 
109
109
  # Creates the name of a table like Rails does for models to table names. This method
@@ -201,8 +201,7 @@ module ActiveSupport #:nodoc:
201
201
 
202
202
  # Returns a new Time representing the start of the day (0:00)
203
203
  def beginning_of_day
204
- #(self - seconds_since_midnight).change(:usec => 0)
205
- change(:hour => 0, :min => 0, :sec => 0, :usec => 0)
204
+ (self - self.seconds_since_midnight).change(:usec => 0)
206
205
  end
207
206
  alias :midnight :beginning_of_day
208
207
  alias :at_midnight :beginning_of_day
@@ -10,7 +10,7 @@ module ActiveSupport #:nodoc:
10
10
  :short => "%d %b %H:%M",
11
11
  :long => "%B %d, %Y %H:%M",
12
12
  :long_ordinal => lambda { |time| time.strftime("%B #{time.day.ordinalize}, %Y %H:%M") },
13
- :rfc822 => "%a, %d %b %Y %H:%M:%S %z"
13
+ :rfc822 => lambda { |time| time.strftime("%a, %d %b %Y %H:%M:%S #{time.formatted_offset(false)}") }
14
14
  }
15
15
 
16
16
  def self.included(base) #:nodoc:
@@ -0,0 +1,36 @@
1
+ class Object
2
+ # Invokes the method identified by the symbol +method+, passing it any arguments
3
+ # and/or the block specified, just like the regular Ruby <tt>Object#send</tt> does.
4
+ #
5
+ # *Unlike* that method however, a +NoMethodError+ exception will *not* be raised
6
+ # and +nil+ will be returned instead, if the receiving object is a +nil+ object or NilClass.
7
+ #
8
+ # ==== Examples
9
+ #
10
+ # Without try
11
+ # @person && @person.name
12
+ # or
13
+ # @person ? @person.name : nil
14
+ #
15
+ # With try
16
+ # @person.try(:name)
17
+ #
18
+ # +try+ also accepts arguments and/or a block, for the method it is trying
19
+ # Person.try(:find, 1)
20
+ # @people.try(:collect) {|p| p.name}
21
+ #--
22
+ # This method definition below is for rdoc purposes only. The alias_method call
23
+ # below overrides it as an optimization since +try+ behaves like +Object#send+,
24
+ # unless called on +NilClass+.
25
+ def try(method, *args, &block)
26
+ send(method, *args, &block)
27
+ end
28
+ remove_method :try
29
+ alias_method :try, :__send__
30
+ end
31
+
32
+ class NilClass
33
+ def try(*args)
34
+ nil
35
+ end
36
+ end
@@ -51,6 +51,9 @@ module ActiveSupport #:nodoc:
51
51
  mattr_accessor :constant_watch_stack
52
52
  self.constant_watch_stack = []
53
53
 
54
+ mattr_accessor :constant_watch_stack_mutex
55
+ self.constant_watch_stack_mutex = Mutex.new
56
+
54
57
  # Module includes this module
55
58
  module ModuleConstMissing #:nodoc:
56
59
  def self.included(base) #:nodoc:
@@ -319,12 +322,7 @@ module ActiveSupport #:nodoc:
319
322
  rescue NameError
320
323
  next
321
324
  end
322
-
323
- [
324
- nesting.camelize,
325
- # Special case: application.rb might define ApplicationControlller.
326
- ('ApplicationController' if nesting == 'application')
327
- ]
325
+ [ nesting_camel ]
328
326
  end.flatten.compact.uniq
329
327
  end
330
328
 
@@ -514,7 +512,9 @@ module ActiveSupport #:nodoc:
514
512
  [mod_name, initial_constants]
515
513
  end
516
514
 
517
- constant_watch_stack.concat watch_frames
515
+ constant_watch_stack_mutex.synchronize do
516
+ constant_watch_stack.concat watch_frames
517
+ end
518
518
 
519
519
  aborting = true
520
520
  begin
@@ -531,8 +531,10 @@ module ActiveSupport #:nodoc:
531
531
  new_constants = mod.local_constant_names - prior_constants
532
532
 
533
533
  # Make sure no other frames takes credit for these constants.
534
- constant_watch_stack.each do |frame_name, constants|
535
- constants.concat new_constants if frame_name == mod_name
534
+ constant_watch_stack_mutex.synchronize do
535
+ constant_watch_stack.each do |frame_name, constants|
536
+ constants.concat new_constants if frame_name == mod_name
537
+ end
536
538
  end
537
539
 
538
540
  new_constants.collect do |suffix|
@@ -554,8 +556,10 @@ module ActiveSupport #:nodoc:
554
556
  # Remove the stack frames that we added.
555
557
  if defined?(watch_frames) && ! watch_frames.blank?
556
558
  frame_ids = watch_frames.collect { |frame| frame.object_id }
557
- constant_watch_stack.delete_if do |watch_frame|
558
- frame_ids.include? watch_frame.object_id
559
+ constant_watch_stack_mutex.synchronize do
560
+ constant_watch_stack.delete_if do |watch_frame|
561
+ frame_ids.include? watch_frame.object_id
562
+ end
559
563
  end
560
564
  end
561
565
  end
@@ -564,9 +568,9 @@ module ActiveSupport #:nodoc:
564
568
  # Old style environment.rb referenced this method directly. Please note, it doesn't
565
569
  # actually *do* anything any more.
566
570
  def self.root(*args)
567
- if defined?(RAILS_DEFAULT_LOGGER)
568
- RAILS_DEFAULT_LOGGER.warn "Your environment.rb uses the old syntax, it may not continue to work in future releases."
569
- RAILS_DEFAULT_LOGGER.warn "For upgrade instructions please see: http://manuals.rubyonrails.com/read/book/19"
571
+ if defined?(Rails) && Rails.logger
572
+ Rails.logger.warn "Your environment.rb uses the old syntax, it may not continue to work in future releases."
573
+ Rails.logger.warn "For upgrade instructions please see: http://manuals.rubyonrails.com/read/book/19"
570
574
  end
571
575
  end
572
576
  end
@@ -13,7 +13,7 @@ module ActiveSupport
13
13
  $stderr.puts callstack.join("\n ") if debug
14
14
  },
15
15
  'development' => Proc.new { |message, callstack|
16
- logger = defined?(::RAILS_DEFAULT_LOGGER) ? ::RAILS_DEFAULT_LOGGER : Logger.new($stderr)
16
+ logger = defined?(Rails) ? Rails.logger : Logger.new($stderr)
17
17
  logger.warn message
18
18
  logger.debug callstack.join("\n ") if debug
19
19
  }
@@ -90,10 +90,15 @@ module ActiveSupport
90
90
  method_names.each do |method_name|
91
91
  alias_method_chain(method_name, :deprecation) do |target, punctuation|
92
92
  class_eval(<<-EOS, __FILE__, __LINE__)
93
- def #{target}_with_deprecation#{punctuation}(*args, &block)
94
- ::ActiveSupport::Deprecation.warn(self.class.deprecated_method_warning(:#{method_name}, #{options[method_name].inspect}), caller)
95
- #{target}_without_deprecation#{punctuation}(*args, &block)
96
- end
93
+ def #{target}_with_deprecation#{punctuation}(*args, &block) # def generate_secret_with_deprecation(*args, &block)
94
+ ::ActiveSupport::Deprecation.warn( # ::ActiveSupport::Deprecation.warn(
95
+ self.class.deprecated_method_warning( # self.class.deprecated_method_warning(
96
+ :#{method_name}, # :generate_secret,
97
+ #{options[method_name].inspect}), # "You should use ActiveSupport::SecureRandom.hex(64)"),
98
+ caller # caller
99
+ ) # )
100
+ #{target}_without_deprecation#{punctuation}(*args, &block) # generate_secret_without_deprecation(*args, &block)
101
+ end # end
97
102
  EOS
98
103
  end
99
104
  end
@@ -113,37 +118,6 @@ module ActiveSupport
113
118
  end
114
119
  end
115
120
 
116
- module Assertions #:nodoc:
117
- def assert_deprecated(match = nil, &block)
118
- result, warnings = collect_deprecations(&block)
119
- assert !warnings.empty?, "Expected a deprecation warning within the block but received none"
120
- if match
121
- match = Regexp.new(Regexp.escape(match)) unless match.is_a?(Regexp)
122
- assert warnings.any? { |w| w =~ match }, "No deprecation warning matched #{match}: #{warnings.join(', ')}"
123
- end
124
- result
125
- end
126
-
127
- def assert_not_deprecated(&block)
128
- result, deprecations = collect_deprecations(&block)
129
- assert deprecations.empty?, "Expected no deprecation warning within the block but received #{deprecations.size}: \n #{deprecations * "\n "}"
130
- result
131
- end
132
-
133
- private
134
- def collect_deprecations
135
- old_behavior = ActiveSupport::Deprecation.behavior
136
- deprecations = []
137
- ActiveSupport::Deprecation.behavior = Proc.new do |message, callstack|
138
- deprecations << message
139
- end
140
- result = yield
141
- [result, deprecations]
142
- ensure
143
- ActiveSupport::Deprecation.behavior = old_behavior
144
- end
145
- end
146
-
147
121
  class DeprecationProxy #:nodoc:
148
122
  silence_warnings do
149
123
  instance_methods.each { |m| undef_method m unless m =~ /^__/ }
@@ -220,24 +194,3 @@ end
220
194
  class Module
221
195
  include ActiveSupport::Deprecation::ClassMethods
222
196
  end
223
-
224
- require 'test/unit/error'
225
-
226
- module Test
227
- module Unit
228
- class TestCase
229
- include ActiveSupport::Deprecation::Assertions
230
- end
231
-
232
- class Error # :nodoc:
233
- # Silence warnings when reporting test errors.
234
- def message_with_silenced_deprecation
235
- ActiveSupport::Deprecation.silence do
236
- message_without_silenced_deprecation
237
- end
238
- end
239
-
240
- alias_method_chain :message, :silenced_deprecation
241
- end
242
- end
243
- end
@@ -1,3 +1,5 @@
1
+ require 'active_support/basic_object'
2
+
1
3
  module ActiveSupport
2
4
  # Provides accurate date and time measurements using Date#advance and
3
5
  # Time#advance, respectively. It mainly supports the methods on Numeric,
@@ -68,7 +70,7 @@ module ActiveSupport
68
70
  [:years, :months, :days, :minutes, :seconds].map do |length|
69
71
  n = consolidated[length]
70
72
  "#{n} #{n == 1 ? length.to_s.singularize : length.to_s}" if n.nonzero?
71
- end.compact.to_sentence
73
+ end.compact.to_sentence(:locale => :en)
72
74
  end
73
75
 
74
76
  protected
@@ -42,6 +42,7 @@ module ActiveSupport
42
42
  inflect.singular(/(vert|ind)ices$/i, '\1ex')
43
43
  inflect.singular(/(matr)ices$/i, '\1ix')
44
44
  inflect.singular(/(quiz)zes$/i, '\1')
45
+ inflect.singular(/(database)s$/i, '\1')
45
46
 
46
47
  inflect.irregular('person', 'people')
47
48
  inflect.irregular('man', 'men')
@@ -254,18 +254,20 @@ module ActiveSupport
254
254
  # @person = Person.find(1)
255
255
  # # => #<Person id: 1, name: "Donald E. Knuth">
256
256
  #
257
- # <%= link_to(@person.name, person_path %>
257
+ # <%= link_to(@person.name, person_path(@person)) %>
258
258
  # # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
259
259
  def parameterize(string, sep = '-')
260
- re_sep = Regexp.escape(sep)
261
260
  # replace accented chars with ther ascii equivalents
262
261
  parameterized_string = transliterate(string)
263
262
  # Turn unwanted chars into the seperator
264
263
  parameterized_string.gsub!(/[^a-z0-9\-_\+]+/i, sep)
265
- # No more than one of the separator in a row.
266
- parameterized_string.squeeze!(sep)
267
- # Remove leading/trailing separator.
268
- parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
264
+ unless sep.blank?
265
+ re_sep = Regexp.escape(sep)
266
+ # No more than one of the separator in a row.
267
+ parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
268
+ # Remove leading/trailing separator.
269
+ parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/i, '')
270
+ end
269
271
  parameterized_string.downcase
270
272
  end
271
273
 
@@ -275,9 +277,16 @@ module ActiveSupport
275
277
  Iconv.iconv('ascii//ignore//translit', 'utf-8', string).to_s
276
278
  end
277
279
 
280
+ if RUBY_VERSION >= '1.9'
281
+ undef_method :transliterate
282
+ def transliterate(string)
283
+ warn "Ruby 1.9 doesn't support Unicode normalization yet"
284
+ string.dup
285
+ end
286
+
278
287
  # The iconv transliteration code doesn't function correctly
279
288
  # on some platforms, but it's very fast where it does function.
280
- if "foo" != (Inflector.transliterate("föö") rescue nil)
289
+ elsif "foo" != (Inflector.transliterate("föö") rescue nil)
281
290
  undef_method :transliterate
282
291
  def transliterate(string)
283
292
  string.mb_chars.normalize(:kd). # Decompose accented characters
@@ -16,7 +16,7 @@ module ActiveSupport
16
16
 
17
17
  protected
18
18
  # matches YAML-formatted dates
19
- DATE_REGEX = /^\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?$/
19
+ DATE_REGEX = /^(?:\d{4}-\d{2}-\d{2}|\d{4}-\d{1,2}-\d{1,2}[ \t]+\d{1,2}:\d{2}:\d{2}(\.[0-9]*)?(([ \t]*)Z|[-+]\d{2}?(:\d{2})?)?)$/
20
20
 
21
21
  # Ensure that ":" and "," are always followed by a space
22
22
  def convert_json_to_yaml(json) #:nodoc:
@@ -43,14 +43,32 @@ module ActiveSupport
43
43
  end
44
44
 
45
45
  if marks.empty?
46
- json.gsub(/\\\//, '/')
46
+ json.gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
47
+ ustr = $1
48
+ if ustr.starts_with?('u')
49
+ [ustr[1..-1].to_i(16)].pack("U")
50
+ elsif ustr == '\\'
51
+ '\\\\'
52
+ else
53
+ ustr
54
+ end
55
+ end
47
56
  else
48
57
  left_pos = [-1].push(*marks)
49
58
  right_pos = marks << scanner.pos + scanner.rest_size
50
59
  output = []
51
60
  left_pos.each_with_index do |left, i|
52
61
  scanner.pos = left.succ
53
- output << scanner.peek(right_pos[i] - scanner.pos + 1)
62
+ output << scanner.peek(right_pos[i] - scanner.pos + 1).gsub(/\\([\\\/]|u[[:xdigit:]]{4})/) do
63
+ ustr = $1
64
+ if ustr.starts_with?('u')
65
+ [ustr[1..-1].to_i(16)].pack("U")
66
+ elsif ustr == '\\'
67
+ '\\\\'
68
+ else
69
+ ustr
70
+ end
71
+ end
54
72
  end
55
73
  output = output * " "
56
74
 
@@ -2,7 +2,7 @@ class Date
2
2
  # Returns a JSON string representing the date. If ActiveSupport.use_standard_json_time_format is set to true, the
3
3
  # ISO 8601 format is used.
4
4
  #
5
- # ==== Examples:
5
+ # ==== Examples
6
6
  #
7
7
  # # With ActiveSupport.use_standard_json_time_format = true
8
8
  # Date.new(2005,2,1).to_json
@@ -2,7 +2,7 @@ class DateTime
2
2
  # Returns a JSON string representing the datetime. If ActiveSupport.use_standard_json_time_format is set to true, the
3
3
  # ISO 8601 format is used.
4
4
  #
5
- # ==== Examples:
5
+ # ==== Examples
6
6
  #
7
7
  # # With ActiveSupport.use_standard_json_time_format = true
8
8
  # DateTime.civil(2005,2,1,15,15,10).to_json
@@ -5,7 +5,7 @@ class Hash
5
5
  # the hash keys. For example:
6
6
  #
7
7
  # { :name => "Konata Izumi", 'age' => 16, 1 => 2 }.to_json
8
- # # => {"name": "Konata Izumi", 1: 2, "age": 16}
8
+ # # => {"name": "Konata Izumi", "1": 2, "age": 16}
9
9
  #
10
10
  # The keys in the JSON string are unordered due to the nature of hashes.
11
11
  #
@@ -31,17 +31,16 @@ class Hash
31
31
  def to_json(options = {}) #:nodoc:
32
32
  hash_keys = self.keys
33
33
 
34
- if options[:except]
35
- hash_keys = hash_keys - Array(options[:except])
36
- elsif options[:only]
37
- hash_keys = hash_keys & Array(options[:only])
34
+ if except = options[:except]
35
+ hash_keys = hash_keys - Array.wrap(except)
36
+ elsif only = options[:only]
37
+ hash_keys = hash_keys & Array.wrap(only)
38
38
  end
39
39
 
40
- returning result = '{' do
41
- result << hash_keys.map do |key|
42
- "#{ActiveSupport::JSON.encode(key)}: #{ActiveSupport::JSON.encode(self[key], options)}"
43
- end * ', '
44
- result << '}'
45
- end
40
+ result = '{'
41
+ result << hash_keys.map do |key|
42
+ "#{ActiveSupport::JSON.encode(key.to_s)}: #{ActiveSupport::JSON.encode(self[key], options)}"
43
+ end * ', '
44
+ result << '}'
46
45
  end
47
46
  end
@@ -2,7 +2,7 @@ class Time
2
2
  # Returns a JSON string representing the time. If ActiveSupport.use_standard_json_time_format is set to true, the
3
3
  # ISO 8601 format is used.
4
4
  #
5
- # ==== Examples:
5
+ # ==== Examples
6
6
  #
7
7
  # # With ActiveSupport.use_standard_json_time_format = true
8
8
  # Time.utc(2005,2,1,15,15,10).to_json
@@ -1,37 +1,31 @@
1
- require 'active_support/json/variable'
2
- require 'active_support/json/encoders/object' # Require explicitly for rdoc.
3
- Dir["#{File.dirname(__FILE__)}/encoders/**/*.rb"].each do |file|
4
- basename = File.basename(file, '.rb')
5
- unless basename == 'object'
6
- require "active_support/json/encoders/#{basename}"
7
- end
8
- end
9
-
10
1
  module ActiveSupport
11
2
  module JSON
12
3
  class CircularReferenceError < StandardError
13
4
  end
14
5
 
15
- class << self
16
- REFERENCE_STACK_VARIABLE = :json_reference_stack #:nodoc:
17
-
18
- # Converts a Ruby object into a JSON string.
19
- def encode(value, options = {})
20
- raise_on_circular_reference(value) do
21
- value.send(:to_json, options)
22
- end
23
- end
24
-
25
- protected
26
- def raise_on_circular_reference(value) #:nodoc:
27
- stack = Thread.current[REFERENCE_STACK_VARIABLE] ||= []
28
- raise CircularReferenceError, 'object references itself' if
29
- stack.include? value
30
- stack << value
31
- yield
32
- ensure
33
- stack.pop
34
- end
6
+ # Converts a Ruby object into a JSON string.
7
+ def self.encode(value, options = {})
8
+ seen = (options[:seen] ||= [])
9
+ raise CircularReferenceError, 'object references itself' if seen.include?(value)
10
+ seen << value
11
+ value.send(:to_json, options)
12
+ ensure
13
+ seen.pop
35
14
  end
36
15
  end
37
16
  end
17
+
18
+ require 'active_support/json/variable'
19
+ require 'active_support/json/encoders/date'
20
+ require 'active_support/json/encoders/date_time'
21
+ require 'active_support/json/encoders/enumerable'
22
+ require 'active_support/json/encoders/false_class'
23
+ require 'active_support/json/encoders/hash'
24
+ require 'active_support/json/encoders/nil_class'
25
+ require 'active_support/json/encoders/numeric'
26
+ require 'active_support/json/encoders/object'
27
+ require 'active_support/json/encoders/regexp'
28
+ require 'active_support/json/encoders/string'
29
+ require 'active_support/json/encoders/symbol'
30
+ require 'active_support/json/encoders/time'
31
+ require 'active_support/json/encoders/true_class'