activesupport 3.1.12 → 3.2.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 (78) hide show
  1. data/CHANGELOG.md +1539 -30
  2. data/README.rdoc +2 -2
  3. data/lib/active_support.rb +1 -1
  4. data/lib/active_support/benchmarkable.rb +13 -18
  5. data/lib/active_support/buffered_logger.rb +43 -55
  6. data/lib/active_support/cache.rb +109 -115
  7. data/lib/active_support/cache/file_store.rb +6 -17
  8. data/lib/active_support/cache/mem_cache_store.rb +10 -2
  9. data/lib/active_support/cache/null_store.rb +44 -0
  10. data/lib/active_support/cache/strategy/local_cache.rb +2 -2
  11. data/lib/active_support/callbacks.rb +38 -35
  12. data/lib/active_support/concern.rb +5 -10
  13. data/lib/active_support/core_ext/array.rb +1 -0
  14. data/lib/active_support/core_ext/array/access.rb +1 -1
  15. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
  16. data/lib/active_support/core_ext/array/wrap.rb +1 -1
  17. data/lib/active_support/core_ext/class.rb +0 -1
  18. data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -2
  19. data/lib/active_support/core_ext/date/calculations.rb +37 -14
  20. data/lib/active_support/core_ext/date/freeze.rb +6 -4
  21. data/lib/active_support/core_ext/date_time/calculations.rb +1 -1
  22. data/lib/active_support/core_ext/enumerable.rb +25 -8
  23. data/lib/active_support/core_ext/file/atomic.rb +1 -2
  24. data/lib/active_support/core_ext/hash/conversions.rb +7 -25
  25. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
  26. data/lib/active_support/core_ext/io.rb +15 -0
  27. data/lib/active_support/core_ext/kernel.rb +0 -1
  28. data/lib/active_support/core_ext/kernel/agnostics.rb +2 -2
  29. data/lib/active_support/core_ext/kernel/debugger.rb +1 -7
  30. data/lib/active_support/core_ext/module.rb +2 -2
  31. data/lib/active_support/core_ext/module/attribute_accessors.rb +6 -2
  32. data/lib/active_support/core_ext/module/delegation.rb +32 -21
  33. data/lib/active_support/core_ext/module/qualified_const.rb +64 -0
  34. data/lib/active_support/core_ext/module/reachable.rb +1 -3
  35. data/lib/active_support/core_ext/module/synchronization.rb +2 -0
  36. data/lib/active_support/core_ext/object/blank.rb +14 -2
  37. data/lib/active_support/core_ext/object/inclusion.rb +17 -7
  38. data/lib/active_support/core_ext/object/to_json.rb +2 -2
  39. data/lib/active_support/core_ext/range/conversions.rb +1 -1
  40. data/lib/active_support/core_ext/string/conversions.rb +2 -2
  41. data/lib/active_support/core_ext/string/inflections.rb +44 -6
  42. data/lib/active_support/core_ext/string/multibyte.rb +1 -1
  43. data/lib/active_support/core_ext/string/output_safety.rb +22 -25
  44. data/lib/active_support/core_ext/time/calculations.rb +66 -12
  45. data/lib/active_support/dependencies.rb +51 -52
  46. data/lib/active_support/file_update_checker.rb +100 -15
  47. data/lib/active_support/hash_with_indifferent_access.rb +5 -1
  48. data/lib/active_support/i18n.rb +1 -1
  49. data/lib/active_support/i18n_railtie.rb +9 -4
  50. data/lib/active_support/inflections.rb +3 -3
  51. data/lib/active_support/inflector/inflections.rb +53 -92
  52. data/lib/active_support/inflector/methods.rb +173 -9
  53. data/lib/active_support/json/decoding.rb +3 -17
  54. data/lib/active_support/json/encoding.rb +11 -14
  55. data/lib/active_support/memoizable.rb +12 -1
  56. data/lib/active_support/message_encryptor.rb +52 -20
  57. data/lib/active_support/message_verifier.rb +15 -4
  58. data/lib/active_support/notifications.rb +87 -14
  59. data/lib/active_support/notifications/instrumenter.rb +1 -2
  60. data/lib/active_support/ordered_hash.rb +7 -3
  61. data/lib/active_support/tagged_logging.rb +63 -0
  62. data/lib/active_support/testing/assertions.rb +1 -1
  63. data/lib/active_support/testing/mochaing.rb +2 -2
  64. data/lib/active_support/testing/performance/ruby.rb +1 -1
  65. data/lib/active_support/testing/setup_and_teardown.rb +4 -12
  66. data/lib/active_support/time_with_zone.rb +6 -3
  67. data/lib/active_support/values/time_zone.rb +3 -7
  68. data/lib/active_support/version.rb +3 -3
  69. data/lib/active_support/xml_mini.rb +3 -3
  70. data/lib/active_support/xml_mini/jdom.rb +4 -10
  71. metadata +28 -21
  72. checksums.yaml +0 -7
  73. data/lib/active_support/cache/compressed_mem_cache_store.rb +0 -13
  74. data/lib/active_support/cache/synchronized_memory_store.rb +0 -11
  75. data/lib/active_support/core_ext/class/inheritable_attributes.rb +0 -178
  76. data/lib/active_support/core_ext/kernel/requires.rb +0 -28
  77. data/lib/active_support/core_ext/module/attr_accessor_with_default.rb +0 -31
  78. data/lib/active_support/secure_random.rb +0 -6
@@ -5,7 +5,7 @@
5
5
  # first call will result in a frozen object error since the memo
6
6
  # instance variable is uninitialized.
7
7
  #
8
- # Work around by eagerly memoizing before freezing.
8
+ # Work around by eagerly memoizing before the first freeze.
9
9
  #
10
10
  # Ruby 1.9 uses a preinitialized instance variable so it's unaffected.
11
11
  # This hack is as close as we can get to feature detection:
@@ -17,9 +17,11 @@ if RUBY_VERSION < '1.9'
17
17
  if frozen_object_error.message =~ /frozen/
18
18
  class Date #:nodoc:
19
19
  def freeze
20
- self.class.private_instance_methods(false).each do |m|
21
- if m.to_s =~ /\A__\d+__\Z/
22
- instance_variable_set(:"@#{m}", [send(m)])
20
+ unless frozen?
21
+ self.class.private_instance_methods(false).each do |m|
22
+ if m.to_s =~ /\A__\d+__\Z/
23
+ instance_variable_set(:"@#{m}", [send(m)])
24
+ end
23
25
  end
24
26
  end
25
27
 
@@ -4,7 +4,7 @@ class DateTime
4
4
  class << self
5
5
  # DateTimes aren't aware of DST rules, so use a consistent non-DST offset when creating a DateTime with an offset in the local zone
6
6
  def local_offset
7
- ::Time.local(2012).utc_offset.to_r / 86400
7
+ ::Time.local(2007).utc_offset.to_r / 86400
8
8
  end
9
9
 
10
10
  # Returns <tt>Time.zone.now.to_datetime</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise returns <tt>Time.now.to_datetime</tt>.
@@ -20,6 +20,7 @@ module Enumerable
20
20
  # "2006-02-24 -> Transcript, Transcript"
21
21
  # "2006-02-23 -> Transcript"
22
22
  def group_by
23
+ return to_enum :group_by unless block_given?
23
24
  assoc = ActiveSupport::OrderedHash.new
24
25
 
25
26
  each do |element|
@@ -62,6 +63,13 @@ module Enumerable
62
63
  end
63
64
  end
64
65
 
66
+ # Plucks the value of the passed method for each element and returns the result as an array. Example:
67
+ #
68
+ # people.pluck(:name) # => [ "David Heinemeier Hansson", "Jamie Heinemeier Hansson" ]
69
+ def pluck(method)
70
+ collect { |element| element.send(method) }
71
+ end
72
+
65
73
  # Iterates over a collection, passing the current element *and* the
66
74
  # +memo+ to the block. Handy for building up hashes or
67
75
  # reducing collections down to one object. Examples:
@@ -75,9 +83,10 @@ module Enumerable
75
83
  #
76
84
  # (1..5).each_with_object(1) { |value, memo| memo *= value } # => 1
77
85
  #
78
- def each_with_object(memo, &block)
86
+ def each_with_object(memo)
87
+ return to_enum :each_with_object, memo unless block_given?
79
88
  each do |element|
80
- block.call(element, memo)
89
+ yield element, memo
81
90
  end
82
91
  memo
83
92
  end unless [].respond_to?(:each_with_object)
@@ -90,17 +99,25 @@ module Enumerable
90
99
  # => { "Chade- Fowlersburg-e" => <Person ...>, "David Heinemeier Hansson" => <Person ...>, ...}
91
100
  #
92
101
  def index_by
102
+ return to_enum :index_by unless block_given?
93
103
  Hash[map { |elem| [yield(elem), elem] }]
94
104
  end
95
105
 
96
- # Returns true if the collection has more than 1 element. Functionally equivalent to collection.size > 1.
97
- # Can be called with a block too, much like any?, so people.many? { |p| p.age > 26 } returns true if more than 1 person is over 26.
98
- def many?(&block)
99
- size = block_given? ? count(&block) : self.size
100
- size > 1
106
+ # Returns true if the enumerable has more than 1 element. Functionally equivalent to enum.to_a.size > 1.
107
+ # Can be called with a block too, much like any?, so <tt>people.many? { |p| p.age > 26 }</tt> returns true if more than one person is over 26.
108
+ def many?
109
+ cnt = 0
110
+ if block_given?
111
+ any? do |element|
112
+ cnt += 1 if yield element
113
+ cnt > 1
114
+ end
115
+ else
116
+ any?{ (cnt += 1) > 1 }
117
+ end
101
118
  end
102
119
 
103
- # The negative of the Enumerable#include?. Returns true if the collection does not include the object.
120
+ # The negative of the <tt>Enumerable#include?</tt>. Returns true if the collection does not include the object.
104
121
  def exclude?(object)
105
122
  !include?(object)
106
123
  end
@@ -1,5 +1,5 @@
1
1
  class File
2
- # Write to a file atomically. Useful for situations where you don't
2
+ # Write to a file atomically. Useful for situations where you don't
3
3
  # want other processes or threads to see half-written files.
4
4
  #
5
5
  # File.atomic_write("important.file") do |file|
@@ -17,7 +17,6 @@ class File
17
17
  require 'fileutils' unless defined?(FileUtils)
18
18
 
19
19
  temp_file = Tempfile.new(basename(file_name), temp_dir)
20
- temp_file.binmode
21
20
  yield temp_file
22
21
  temp_file.close
23
22
 
@@ -85,33 +85,15 @@ class Hash
85
85
  end
86
86
  end
87
87
 
88
- class DisallowedType < StandardError #:nodoc:
89
- def initialize(type)
90
- super "Disallowed type attribute: #{type.inspect}"
91
- end
92
- end
93
-
94
- DISALLOWED_XML_TYPES = %w(symbol yaml)
95
-
96
88
  class << self
97
- def from_xml(xml, disallowed_types = nil)
98
- typecast_xml_value(unrename_keys(ActiveSupport::XmlMini.parse(xml)), disallowed_types)
99
- end
100
-
101
- def from_trusted_xml(xml)
102
- from_xml xml, []
89
+ def from_xml(xml)
90
+ typecast_xml_value(unrename_keys(ActiveSupport::XmlMini.parse(xml)))
103
91
  end
104
92
 
105
93
  private
106
- def typecast_xml_value(value, disallowed_types = nil)
107
- disallowed_types ||= DISALLOWED_XML_TYPES
108
-
94
+ def typecast_xml_value(value)
109
95
  case value.class.to_s
110
96
  when 'Hash'
111
- if value.include?('type') && !value['type'].is_a?(Hash) && disallowed_types.include?(value['type'])
112
- raise DisallowedType, value['type']
113
- end
114
-
115
97
  if value['type'] == 'array'
116
98
  _, entries = Array.wrap(value.detect { |k,v| not v.is_a?(String) })
117
99
  if entries.nil? || (c = value['__content__'] && c.blank?)
@@ -119,9 +101,9 @@ class Hash
119
101
  else
120
102
  case entries.class.to_s # something weird with classes not matching here. maybe singleton methods breaking is_a?
121
103
  when "Array"
122
- entries.collect { |v| typecast_xml_value(v, disallowed_types) }
104
+ entries.collect { |v| typecast_xml_value(v) }
123
105
  when "Hash"
124
- [typecast_xml_value(entries, disallowed_types)]
106
+ [typecast_xml_value(entries)]
125
107
  else
126
108
  raise "can't typecast #{entries.inspect}"
127
109
  end
@@ -145,14 +127,14 @@ class Hash
145
127
  elsif value['type'] && value.size == 1 && !value['type'].is_a?(::Hash)
146
128
  nil
147
129
  else
148
- xml_value = Hash[value.map { |k,v| [k, typecast_xml_value(v, disallowed_types)] }]
130
+ xml_value = Hash[value.map { |k,v| [k, typecast_xml_value(v)] }]
149
131
 
150
132
  # Turn { :files => { :file => #<StringIO> } into { :files => #<StringIO> } so it is compatible with
151
133
  # how multipart uploaded files from HTML appear
152
134
  xml_value["file"].is_a?(StringIO) ? xml_value["file"] : xml_value
153
135
  end
154
136
  when 'Array'
155
- value.map! { |i| typecast_xml_value(i, disallowed_types) }
137
+ value.map! { |i| typecast_xml_value(i) }
156
138
  value.length > 1 ? value : value.first
157
139
  when 'String'
158
140
  value
@@ -2,7 +2,7 @@ require 'active_support/hash_with_indifferent_access'
2
2
 
3
3
  class Hash
4
4
 
5
- # Returns an +ActiveSupport::HashWithIndifferentAccess+ out of its receiver:
5
+ # Returns an <tt>ActiveSupport::HashWithIndifferentAccess</tt> out of its receiver:
6
6
  #
7
7
  # {:a => 1}.with_indifferent_access["a"] # => 1
8
8
  #
@@ -0,0 +1,15 @@
1
+ if RUBY_VERSION < '1.9.2'
2
+
3
+ # :stopdoc:
4
+ class IO
5
+ def self.binread(name, length = nil, offset = nil)
6
+ return File.read name unless length || offset
7
+ File.open(name, 'rb') { |f|
8
+ f.seek offset if offset
9
+ f.read length
10
+ }
11
+ end
12
+ end
13
+ # :startdoc:
14
+
15
+ end
@@ -1,5 +1,4 @@
1
1
  require 'active_support/core_ext/kernel/reporting'
2
2
  require 'active_support/core_ext/kernel/agnostics'
3
- require 'active_support/core_ext/kernel/requires'
4
3
  require 'active_support/core_ext/kernel/debugger'
5
4
  require 'active_support/core_ext/kernel/singleton_class'
@@ -1,11 +1,11 @@
1
1
  class Object
2
2
  # Makes backticks behave (somewhat more) similarly on all platforms.
3
3
  # On win32 `nonexistent_command` raises Errno::ENOENT; on Unix, the
4
- # spawned shell prints a message to stderr and sets $?. We emulate
4
+ # spawned shell prints a message to stderr and sets $?. We emulate
5
5
  # Unix on the former but not the latter.
6
6
  def `(command) #:nodoc:
7
7
  super
8
8
  rescue Errno::ENOENT => e
9
9
  STDERR.puts "#$0: #{e}"
10
10
  end
11
- end
11
+ end
@@ -5,12 +5,6 @@ module Kernel
5
5
  message = "\n***** Debugger requested, but was not available (ensure ruby-debug is listed in Gemfile/installed as gem): Start server with --debugger to enable *****\n"
6
6
  defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
7
7
  end
8
- end
9
-
10
- undef :breakpoint if respond_to?(:breakpoint)
11
- def breakpoint
12
- message = "\n***** The 'breakpoint' command has been renamed 'debugger' -- please change *****\n"
13
- defined?(Rails) ? Rails.logger.info(message) : $stderr.puts(message)
14
- debugger
8
+ alias breakpoint debugger unless respond_to?(:breakpoint)
15
9
  end
16
10
  end
@@ -4,9 +4,9 @@ require 'active_support/core_ext/module/anonymous'
4
4
  require 'active_support/core_ext/module/reachable'
5
5
  require 'active_support/core_ext/module/attribute_accessors'
6
6
  require 'active_support/core_ext/module/attr_internal'
7
- require 'active_support/core_ext/module/attr_accessor_with_default'
8
7
  require 'active_support/core_ext/module/delegation'
9
8
  require 'active_support/core_ext/module/synchronization'
10
9
  require 'active_support/core_ext/module/deprecation'
11
10
  require 'active_support/core_ext/module/remove_method'
12
- require 'active_support/core_ext/module/method_names'
11
+ require 'active_support/core_ext/module/method_names'
12
+ require 'active_support/core_ext/module/qualified_const'
@@ -12,7 +12,7 @@ class Module
12
12
  end
13
13
  EOS
14
14
 
15
- unless options[:instance_reader] == false
15
+ unless options[:instance_reader] == false || options[:instance_accessor] == false
16
16
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
17
17
  def #{sym}
18
18
  @@#{sym}
@@ -31,7 +31,7 @@ class Module
31
31
  end
32
32
  EOS
33
33
 
34
- unless options[:instance_writer] == false
34
+ unless options[:instance_writer] == false || options[:instance_accessor] == false
35
35
  class_eval(<<-EOS, __FILE__, __LINE__ + 1)
36
36
  def #{sym}=(obj)
37
37
  @@#{sym} = obj
@@ -53,6 +53,10 @@ class Module
53
53
  # end
54
54
  #
55
55
  # AppConfiguration.google_api_key = "overriding the api key!"
56
+ #
57
+ # To opt out of the instance writer method, pass :instance_writer => false.
58
+ # To opt out of the instance reader method, pass :instance_reader => false.
59
+ # To opt out of both instance methods, pass :instance_accessor => false.
56
60
  def mattr_accessor(*syms)
57
61
  mattr_reader(*syms)
58
62
  mattr_writer(*syms)
@@ -1,5 +1,3 @@
1
- require "active_support/core_ext/module/remove_method"
2
-
3
1
  class Module
4
2
  # Provides a delegate class method to easily expose contained objects' methods
5
3
  # as your own. Pass one or more methods (specified as symbols or strings)
@@ -108,35 +106,48 @@ class Module
108
106
  unless options.is_a?(Hash) && to = options[:to]
109
107
  raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)."
110
108
  end
109
+ prefix, to, allow_nil = options[:prefix], options[:to], options[:allow_nil]
111
110
 
112
- if options[:prefix] == true && options[:to].to_s =~ /^[^a-z_]/
111
+ if prefix == true && to.to_s =~ /^[^a-z_]/
113
112
  raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
114
113
  end
115
114
 
116
- prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_" || ''
115
+ method_prefix =
116
+ if prefix
117
+ "#{prefix == true ? to : prefix}_"
118
+ else
119
+ ''
120
+ end
117
121
 
118
122
  file, line = caller.first.split(':', 2)
119
123
  line = line.to_i
120
124
 
121
125
  methods.each do |method|
122
- on_nil =
123
- if options[:allow_nil]
124
- 'return'
125
- else
126
- %(raise "#{self}##{prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
127
- end
126
+ method = method.to_s
127
+
128
+ if allow_nil
129
+ module_eval(<<-EOS, file, line - 2)
130
+ def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block)
131
+ if #{to} || #{to}.respond_to?(:#{method}) # if client || client.respond_to?(:name)
132
+ #{to}.__send__(:#{method}, *args, &block) # client.__send__(:name, *args, &block)
133
+ end # end
134
+ end # end
135
+ EOS
136
+ else
137
+ exception = %(raise "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
128
138
 
129
- module_eval(<<-EOS, file, line - 1)
130
- def #{prefix}#{method}(*args, &block) # def customer_name(*args, &block)
131
- #{to}.__send__(#{method.inspect}, *args, &block) # client.__send__(:name, *args, &block)
132
- rescue NoMethodError # rescue NoMethodError
133
- if #{to}.nil? # if client.nil?
134
- #{on_nil} # return # depends on :allow_nil
135
- else # else
136
- raise # raise
137
- end # end
138
- end # end
139
- EOS
139
+ module_eval(<<-EOS, file, line - 1)
140
+ def #{method_prefix}#{method}(*args, &block) # def customer_name(*args, &block)
141
+ #{to}.__send__(:#{method}, *args, &block) # client.__send__(:name, *args, &block)
142
+ rescue NoMethodError # rescue NoMethodError
143
+ if #{to}.nil? # if client.nil?
144
+ #{exception} # # add helpful message to the exception
145
+ else # else
146
+ raise # raise
147
+ end # end
148
+ end # end
149
+ EOS
150
+ end
140
151
  end
141
152
  end
142
153
  end
@@ -0,0 +1,64 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+
3
+ #--
4
+ # Allows code reuse in the methods below without polluting Module.
5
+ #++
6
+ module QualifiedConstUtils
7
+ def self.raise_if_absolute(path)
8
+ raise NameError, "wrong constant name #$&" if path =~ /\A::[^:]+/
9
+ end
10
+
11
+ def self.names(path)
12
+ path.split('::')
13
+ end
14
+ end
15
+
16
+ ##
17
+ # Extends the API for constants to be able to deal with qualified names. Arguments
18
+ # are assumed to be relative to the receiver.
19
+ #
20
+ #--
21
+ # Qualified names are required to be relative because we are extending existing
22
+ # methods that expect constant names, ie, relative paths of length 1. For example,
23
+ # Object.const_get("::String") raises NameError and so does qualified_const_get.
24
+ #++
25
+ class Module
26
+ if method(:const_defined?).arity == 1
27
+ def qualified_const_defined?(path)
28
+ QualifiedConstUtils.raise_if_absolute(path)
29
+
30
+ QualifiedConstUtils.names(path).inject(self) do |mod, name|
31
+ return unless mod.const_defined?(name)
32
+ mod.const_get(name)
33
+ end
34
+ return true
35
+ end
36
+ else
37
+ def qualified_const_defined?(path, search_parents=true)
38
+ QualifiedConstUtils.raise_if_absolute(path)
39
+
40
+ QualifiedConstUtils.names(path).inject(self) do |mod, name|
41
+ return unless mod.const_defined?(name, search_parents)
42
+ mod.const_get(name)
43
+ end
44
+ return true
45
+ end
46
+ end
47
+
48
+ def qualified_const_get(path)
49
+ QualifiedConstUtils.raise_if_absolute(path)
50
+
51
+ QualifiedConstUtils.names(path).inject(self) do |mod, name|
52
+ mod.const_get(name)
53
+ end
54
+ end
55
+
56
+ def qualified_const_set(path, value)
57
+ QualifiedConstUtils.raise_if_absolute(path)
58
+
59
+ const_name = path.demodulize
60
+ mod_name = path.deconstantize
61
+ mod = mod_name.empty? ? self : qualified_const_get(mod_name)
62
+ mod.const_set(const_name, value)
63
+ end
64
+ end
@@ -3,8 +3,6 @@ require 'active_support/core_ext/string/inflections'
3
3
 
4
4
  class Module
5
5
  def reachable? #:nodoc:
6
- !anonymous? && name.constantize.equal?(self)
7
- rescue NameError
8
- false
6
+ !anonymous? && name.safe_constantize.equal?(self)
9
7
  end
10
8
  end
@@ -1,6 +1,7 @@
1
1
  require 'thread'
2
2
  require 'active_support/core_ext/module/aliasing'
3
3
  require 'active_support/core_ext/array/extract_options'
4
+ require 'active_support/core_ext/module/deprecation'
4
5
 
5
6
  class Module
6
7
  # Synchronize access around a method, delegating synchronization to a
@@ -40,4 +41,5 @@ class Module
40
41
  alias_method_chain method, :synchronization
41
42
  end
42
43
  end
44
+ deprecate :synchronize
43
45
  end