activesupport 4.1.16 → 4.2.0.beta1

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +140 -714
  3. data/README.rdoc +7 -2
  4. data/lib/active_support/backtrace_cleaner.rb +4 -4
  5. data/lib/active_support/cache.rb +18 -20
  6. data/lib/active_support/cache/file_store.rb +5 -0
  7. data/lib/active_support/cache/strategy/local_cache.rb +5 -4
  8. data/lib/active_support/cache/strategy/local_cache_middleware.rb +5 -0
  9. data/lib/active_support/callbacks.rb +92 -140
  10. data/lib/active_support/concern.rb +9 -1
  11. data/lib/active_support/core_ext/array/access.rb +5 -1
  12. data/lib/active_support/core_ext/array/grouping.rb +5 -0
  13. data/lib/active_support/core_ext/class/delegating_attributes.rb +4 -0
  14. data/lib/active_support/core_ext/date_time/calculations.rb +11 -1
  15. data/lib/active_support/core_ext/date_time/conversions.rb +2 -2
  16. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  17. data/lib/active_support/core_ext/hash.rb +1 -0
  18. data/lib/active_support/core_ext/hash/conversions.rb +2 -3
  19. data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
  20. data/lib/active_support/core_ext/hash/keys.rb +10 -6
  21. data/lib/active_support/core_ext/hash/transform_values.rb +23 -0
  22. data/lib/active_support/core_ext/kernel.rb +3 -2
  23. data/lib/active_support/core_ext/kernel/concern.rb +10 -0
  24. data/lib/active_support/core_ext/kernel/reporting.rb +14 -0
  25. data/lib/active_support/core_ext/load_error.rb +4 -1
  26. data/lib/active_support/core_ext/module/delegation.rb +13 -25
  27. data/lib/active_support/core_ext/numeric/time.rb +1 -19
  28. data/lib/active_support/core_ext/object.rb +1 -0
  29. data/lib/active_support/core_ext/object/duplicable.rb +4 -11
  30. data/lib/active_support/core_ext/object/itself.rb +12 -0
  31. data/lib/active_support/core_ext/object/json.rb +1 -1
  32. data/lib/active_support/core_ext/object/to_query.rb +2 -1
  33. data/lib/active_support/core_ext/object/with_options.rb +15 -2
  34. data/lib/active_support/core_ext/string/access.rb +4 -4
  35. data/lib/active_support/core_ext/string/filters.rb +25 -1
  36. data/lib/active_support/core_ext/string/inflections.rb +3 -1
  37. data/lib/active_support/core_ext/string/output_safety.rb +29 -19
  38. data/lib/active_support/core_ext/thread.rb +7 -0
  39. data/lib/active_support/core_ext/time/conversions.rb +1 -1
  40. data/lib/active_support/core_ext/time/zones.rb +0 -1
  41. data/lib/active_support/dependencies.rb +5 -4
  42. data/lib/active_support/duration.rb +2 -3
  43. data/lib/active_support/gem_version.rb +3 -3
  44. data/lib/active_support/hash_with_indifferent_access.rb +13 -5
  45. data/lib/active_support/i18n_railtie.rb +1 -7
  46. data/lib/active_support/inflector/inflections.rb +1 -1
  47. data/lib/active_support/inflector/methods.rb +39 -15
  48. data/lib/active_support/json/encoding.rb +0 -4
  49. data/lib/active_support/logger.rb +0 -14
  50. data/lib/active_support/logger_silence.rb +3 -24
  51. data/lib/active_support/message_encryptor.rb +2 -1
  52. data/lib/active_support/multibyte/unicode.rb +5 -3
  53. data/lib/active_support/notifications.rb +7 -2
  54. data/lib/active_support/notifications/fanout.rb +11 -6
  55. data/lib/active_support/number_helper.rb +7 -8
  56. data/lib/active_support/number_helper/number_to_rounded_converter.rb +2 -2
  57. data/lib/active_support/test_case.rb +3 -13
  58. data/lib/active_support/testing/assertions.rb +1 -1
  59. data/lib/active_support/testing/declarative.rb +1 -25
  60. data/lib/active_support/testing/isolation.rb +16 -6
  61. data/lib/active_support/testing/tagged_logging.rb +1 -1
  62. data/lib/active_support/testing/time_helpers.rb +5 -1
  63. data/lib/active_support/time.rb +0 -2
  64. data/lib/active_support/time_with_zone.rb +14 -3
  65. data/lib/active_support/values/time_zone.rb +76 -75
  66. data/lib/active_support/xml_mini.rb +0 -3
  67. data/lib/active_support/xml_mini/jdom.rb +5 -6
  68. data/lib/active_support/xml_mini/rexml.rb +5 -6
  69. metadata +17 -16
  70. data/lib/active_support/core_ext/object/to_json.rb +0 -5
  71. data/lib/active_support/file_watcher.rb +0 -36
  72. data/lib/active_support/security_utils.rb +0 -27
@@ -26,7 +26,7 @@ module ActiveSupport
26
26
  # scope :disabled, -> { where(disabled: true) }
27
27
  # end
28
28
  #
29
- # module ClassMethods
29
+ # class_methods do
30
30
  # ...
31
31
  # end
32
32
  # end
@@ -130,5 +130,13 @@ module ActiveSupport
130
130
  super
131
131
  end
132
132
  end
133
+
134
+ def class_methods(&class_methods_module_definition)
135
+ mod = const_defined?(:ClassMethods) ?
136
+ const_get(:ClassMethods) :
137
+ const_set(:ClassMethods, Module.new)
138
+
139
+ mod.module_eval(&class_methods_module_definition)
140
+ end
133
141
  end
134
142
  end
@@ -5,6 +5,8 @@ class Array
5
5
  # %w( a b c d ).from(2) # => ["c", "d"]
6
6
  # %w( a b c d ).from(10) # => []
7
7
  # %w().from(0) # => []
8
+ # %w( a b c d ).from(-2) # => ["c", "d"]
9
+ # %w( a b c ).from(-10) # => []
8
10
  def from(position)
9
11
  self[position, length] || []
10
12
  end
@@ -15,8 +17,10 @@ class Array
15
17
  # %w( a b c d ).to(2) # => ["a", "b", "c"]
16
18
  # %w( a b c d ).to(10) # => ["a", "b", "c", "d"]
17
19
  # %w().to(0) # => []
20
+ # %w( a b c d ).to(-2) # => ["a", "b", "c"]
21
+ # %w( a b c ).to(-10) # => []
18
22
  def to(position)
19
- first position + 1
23
+ self[0..position]
20
24
  end
21
25
 
22
26
  # Equal to <tt>self[1]</tt>.
@@ -18,6 +18,11 @@ class Array
18
18
  # ["3", "4"]
19
19
  # ["5"]
20
20
  def in_groups_of(number, fill_with = nil)
21
+ if number.to_i <= 0
22
+ raise ArgumentError,
23
+ "Group size must be a positive integer, was #{number.inspect}"
24
+ end
25
+
21
26
  if fill_with == false
22
27
  collection = self
23
28
  else
@@ -1,5 +1,7 @@
1
1
  require 'active_support/core_ext/kernel/singleton_class'
2
2
  require 'active_support/core_ext/module/remove_method'
3
+ require 'active_support/core_ext/module/deprecation'
4
+
3
5
 
4
6
  class Class
5
7
  def superclass_delegating_accessor(name, options = {})
@@ -21,6 +23,8 @@ class Class
21
23
  end
22
24
  end
23
25
 
26
+ deprecate superclass_delegating_accessor: :class_attribute
27
+
24
28
  private
25
29
  # Take the object being set and store it in a method. This gives us automatic
26
30
  # inheritance behavior, without having to store the object in an instance
@@ -53,6 +53,16 @@ class DateTime
53
53
  # <tt>:months</tt>, <tt>:weeks</tt>, <tt>:days</tt>, <tt>:hours</tt>,
54
54
  # <tt>:minutes</tt>, <tt>:seconds</tt>.
55
55
  def advance(options)
56
+ unless options[:weeks].nil?
57
+ options[:weeks], partial_weeks = options[:weeks].divmod(1)
58
+ options[:days] = options.fetch(:days, 0) + 7 * partial_weeks
59
+ end
60
+
61
+ unless options[:days].nil?
62
+ options[:days], partial_days = options[:days].divmod(1)
63
+ options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
64
+ end
65
+
56
66
  d = to_date.advance(options)
57
67
  datetime_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
58
68
  seconds_to_advance = \
@@ -63,7 +73,7 @@ class DateTime
63
73
  if seconds_to_advance.zero?
64
74
  datetime_advanced_by_date
65
75
  else
66
- datetime_advanced_by_date.since seconds_to_advance
76
+ datetime_advanced_by_date.since(seconds_to_advance)
67
77
  end
68
78
  end
69
79
 
@@ -71,9 +71,9 @@ class DateTime
71
71
  civil(year, month, day, hour, min, sec, offset)
72
72
  end
73
73
 
74
- # Converts +self+ to a floating-point number of seconds since the Unix epoch.
74
+ # Converts +self+ to a floating-point number of seconds, including fractional microseconds, since the Unix epoch.
75
75
  def to_f
76
- seconds_since_unix_epoch.to_f
76
+ seconds_since_unix_epoch.to_f + sec_fraction
77
77
  end
78
78
 
79
79
  # Converts +self+ to an integer number of seconds since the Unix epoch.
@@ -0,0 +1,51 @@
1
+ require 'securerandom'
2
+
3
+ module Digest
4
+ module UUID
5
+ DNS_NAMESPACE = "k\xA7\xB8\x10\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
6
+ URL_NAMESPACE = "k\xA7\xB8\x11\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
7
+ OID_NAMESPACE = "k\xA7\xB8\x12\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
8
+ X500_NAMESPACE = "k\xA7\xB8\x14\x9D\xAD\x11\xD1\x80\xB4\x00\xC0O\xD40\xC8" #:nodoc:
9
+
10
+ # Generates a v5 non-random UUID (Universally Unique IDentifier).
11
+ #
12
+ # Using Digest::MD5 generates version 3 UUIDs; Digest::SHA1 generates version 5 UUIDs.
13
+ # uuid_from_hash always generates the same UUID for a given name and namespace combination.
14
+ #
15
+ # See RFC 4122 for details of UUID at: http://www.ietf.org/rfc/rfc4122.txt
16
+ def self.uuid_from_hash(hash_class, uuid_namespace, name)
17
+ if hash_class == Digest::MD5
18
+ version = 3
19
+ elsif hash_class == Digest::SHA1
20
+ version = 5
21
+ else
22
+ raise ArgumentError, "Expected Digest::SHA1 or Digest::MD5, got #{hash_class.name}."
23
+ end
24
+
25
+ hash = hash_class.new
26
+ hash.update(uuid_namespace)
27
+ hash.update(name)
28
+
29
+ ary = hash.digest.unpack('NnnnnN')
30
+ ary[2] = (ary[2] & 0x0FFF) | (version << 12)
31
+ ary[3] = (ary[3] & 0x3FFF) | 0x8000
32
+
33
+ "%08x-%04x-%04x-%04x-%04x%08x" % ary
34
+ end
35
+
36
+ # Convenience method for uuid_from_hash using Digest::MD5.
37
+ def self.uuid_v3(uuid_namespace, name)
38
+ self.uuid_from_hash(Digest::MD5, uuid_namespace, name)
39
+ end
40
+
41
+ # Convenience method for uuid_from_hash using Digest::SHA1.
42
+ def self.uuid_v5(uuid_namespace, name)
43
+ self.uuid_from_hash(Digest::SHA1, uuid_namespace, name)
44
+ end
45
+
46
+ # Convenience method for SecureRandom.uuid.
47
+ def self.uuid_v4
48
+ SecureRandom.uuid
49
+ end
50
+ end
51
+ end
@@ -6,3 +6,4 @@ require 'active_support/core_ext/hash/indifferent_access'
6
6
  require 'active_support/core_ext/hash/keys'
7
7
  require 'active_support/core_ext/hash/reverse_merge'
8
8
  require 'active_support/core_ext/hash/slice'
9
+ require 'active_support/core_ext/hash/transform_values'
@@ -105,7 +105,7 @@ class Hash
105
105
  # hash = Hash.from_xml(xml)
106
106
  # # => {"hash"=>{"foo"=>1, "bar"=>2}}
107
107
  #
108
- # DisallowedType is raised if the XML contains attributes with <tt>type="yaml"</tt> or
108
+ # +DisallowedType+ is raised if the XML contains attributes with <tt>type="yaml"</tt> or
109
109
  # <tt>type="symbol"</tt>. Use <tt>Hash.from_trusted_xml</tt> to parse this XML.
110
110
  def from_xml(xml, disallowed_types = nil)
111
111
  ActiveSupport::XMLConverter.new(xml, disallowed_types).to_h
@@ -221,7 +221,7 @@ module ActiveSupport
221
221
  def garbage?(value)
222
222
  # If the type is the only element which makes it then
223
223
  # this still makes the value nil, except if type is
224
- # a XML node(where type['value'] is a Hash)
224
+ # an XML node(where type['value'] is a Hash)
225
225
  value['type'] && !value['type'].is_a?(::Hash) && value.size == 1
226
226
  end
227
227
 
@@ -241,4 +241,3 @@ module ActiveSupport
241
241
 
242
242
  end
243
243
  end
244
-
@@ -18,6 +18,6 @@ class Hash
18
18
  #
19
19
  # b = { b: 1 }
20
20
  # { a: b }.with_indifferent_access['a'] # calls b.nested_under_indifferent_access
21
- # # => {"b"=>32}
21
+ # # => {"b"=>1}
22
22
  alias nested_under_indifferent_access with_indifferent_access
23
23
  end
@@ -6,7 +6,8 @@ class Hash
6
6
  # hash.transform_keys{ |key| key.to_s.upcase }
7
7
  # # => {"NAME"=>"Rob", "AGE"=>"28"}
8
8
  def transform_keys
9
- result = {}
9
+ return enum_for(:transform_keys) unless block_given?
10
+ result = self.class.new
10
11
  each_key do |key|
11
12
  result[yield(key)] = self[key]
12
13
  end
@@ -16,6 +17,7 @@ class Hash
16
17
  # Destructively convert all keys using the block operations.
17
18
  # Same as transform_keys but modifies +self+.
18
19
  def transform_keys!
20
+ return enum_for(:transform_keys!) unless block_given?
19
21
  keys.each do |key|
20
22
  self[yield(key)] = delete(key)
21
23
  end
@@ -27,7 +29,7 @@ class Hash
27
29
  # hash = { name: 'Rob', age: '28' }
28
30
  #
29
31
  # hash.stringify_keys
30
- # # => { "name" => "Rob", "age" => "28" }
32
+ # # => {"name"=>"Rob", "age"=>"28"}
31
33
  def stringify_keys
32
34
  transform_keys{ |key| key.to_s }
33
35
  end
@@ -44,7 +46,7 @@ class Hash
44
46
  # hash = { 'name' => 'Rob', 'age' => '28' }
45
47
  #
46
48
  # hash.symbolize_keys
47
- # # => { name: "Rob", age: "28" }
49
+ # # => {:name=>"Rob", :age=>"28"}
48
50
  def symbolize_keys
49
51
  transform_keys{ |key| key.to_sym rescue key }
50
52
  end
@@ -57,9 +59,11 @@ class Hash
57
59
  end
58
60
  alias_method :to_options!, :symbolize_keys!
59
61
 
60
- # Validate all keys in a hash match <tt>*valid_keys</tt>, raising ArgumentError
61
- # on a mismatch. Note that keys are NOT treated indifferently, meaning if you
62
- # use strings for keys but assert symbols as keys, this will fail.
62
+ # Validate all keys in a hash match <tt>*valid_keys</tt>, raising
63
+ # ArgumentError on a mismatch.
64
+ #
65
+ # Note that keys are treated differently than HashWithIndifferentAccess,
66
+ # meaning that string and symbol keys will not match.
63
67
  #
64
68
  # { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age"
65
69
  # { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'"
@@ -0,0 +1,23 @@
1
+ class Hash
2
+ # Returns a new hash with the results of running +block+ once for every value.
3
+ # The keys are unchanged.
4
+ #
5
+ # { a: 1, b: 2, c: 3 }.transform_values { |x| x * 2 }
6
+ # # => { a: 2, b: 4, c: 6 }
7
+ def transform_values
8
+ return enum_for(:transform_values) unless block_given?
9
+ result = self.class.new
10
+ each do |key, value|
11
+ result[key] = yield(value)
12
+ end
13
+ result
14
+ end
15
+
16
+ # Destructive +transform_values+
17
+ def transform_values!
18
+ return enum_for(:transform_values!) unless block_given?
19
+ each do |key, value|
20
+ self[key] = yield(value)
21
+ end
22
+ end
23
+ end
@@ -1,4 +1,5 @@
1
- require 'active_support/core_ext/kernel/reporting'
2
1
  require 'active_support/core_ext/kernel/agnostics'
3
- require 'active_support/core_ext/kernel/debugger'
2
+ require 'active_support/core_ext/kernel/concern'
3
+ require 'active_support/core_ext/kernel/debugger' if RUBY_VERSION < '2.0.0'
4
+ require 'active_support/core_ext/kernel/reporting'
4
5
  require 'active_support/core_ext/kernel/singleton_class'
@@ -0,0 +1,10 @@
1
+ require 'active_support/core_ext/module/concerning'
2
+
3
+ module Kernel
4
+ # A shortcut to define a toplevel concern, not within a module.
5
+ #
6
+ # See Module::Concerning for more.
7
+ def concern(topic, &module_definition)
8
+ Object.concern topic, &module_definition
9
+ end
10
+ end
@@ -31,9 +31,13 @@ module Kernel
31
31
 
32
32
  # For compatibility
33
33
  def silence_stderr #:nodoc:
34
+ ActiveSupport::Deprecation.warn(
35
+ "#silence_stderr is deprecated and will be removed in the next release"
36
+ ) #not thread-safe
34
37
  silence_stream(STDERR) { yield }
35
38
  end
36
39
 
40
+ # Deprecated : this method is not thread safe
37
41
  # Silences any stream for the duration of the block.
38
42
  #
39
43
  # silence_stream(STDOUT) do
@@ -41,6 +45,8 @@ module Kernel
41
45
  # end
42
46
  #
43
47
  # puts 'But this will'
48
+ #
49
+ # This method is not thread-safe.
44
50
  def silence_stream(stream)
45
51
  old_stream = stream.dup
46
52
  stream.reopen(RbConfig::CONFIG['host_os'] =~ /mswin|mingw/ ? 'NUL:' : '/dev/null')
@@ -80,6 +86,9 @@ module Kernel
80
86
  # stream = capture(:stderr) { system('echo error 1>&2') }
81
87
  # stream # => "error\n"
82
88
  def capture(stream)
89
+ ActiveSupport::Deprecation.warn(
90
+ "#capture(stream) is deprecated and will be removed in the next release"
91
+ ) #not thread-safe
83
92
  stream = stream.to_s
84
93
  captured_stream = Tempfile.new(stream)
85
94
  stream_io = eval("$#{stream}")
@@ -100,7 +109,12 @@ module Kernel
100
109
  # Silences both STDOUT and STDERR, even for subprocesses.
101
110
  #
102
111
  # quietly { system 'bundle install' }
112
+ #
113
+ # This method is not thread-safe.
103
114
  def quietly
115
+ ActiveSupport::Deprecation.warn(
116
+ "#quietly is deprecated and will be removed in the next release"
117
+ ) #not thread-safe
104
118
  silence_stream(STDOUT) do
105
119
  silence_stream(STDERR) do
106
120
  yield
@@ -7,6 +7,7 @@ class LoadError
7
7
  ]
8
8
 
9
9
  unless method_defined?(:path)
10
+ # Returns the path which was unable to be loaded.
10
11
  def path
11
12
  @path ||= begin
12
13
  REGEXPS.find do |regex|
@@ -17,9 +18,11 @@ class LoadError
17
18
  end
18
19
  end
19
20
 
21
+ # Returns true if the given path name (except perhaps for the ".rb"
22
+ # extension) is the missing file which caused the exception to be raised.
20
23
  def is_missing?(location)
21
24
  location.sub(/\.rb$/, '') == path.sub(/\.rb$/, '')
22
25
  end
23
26
  end
24
27
 
25
- MissingSourceFile = LoadError
28
+ MissingSourceFile = LoadError
@@ -170,38 +170,26 @@ class Module
170
170
  # methods still accept two arguments.
171
171
  definition = (method =~ /[^\]]=$/) ? 'arg' : '*args, &block'
172
172
 
173
- # The following generated methods call the target exactly once, storing
173
+ # The following generated method calls the target exactly once, storing
174
174
  # the returned value in a dummy variable.
175
175
  #
176
176
  # Reason is twofold: On one hand doing less calls is in general better.
177
177
  # On the other hand it could be that the target has side-effects,
178
178
  # whereas conceptually, from the user point of view, the delegator should
179
179
  # be doing one call.
180
- if allow_nil
181
- method_def = [
182
- "def #{method_prefix}#{method}(#{definition})", # def customer_name(*args, &block)
183
- "_ = #{to}", # _ = client
184
- "if !_.nil? || nil.respond_to?(:#{method})", # if !_.nil? || nil.respond_to?(:name)
185
- " _.#{method}(#{definition})", # _.name(*args, &block)
186
- "end", # end
187
- "end" # end
188
- ].join ';'
189
- else
190
- exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
191
180
 
192
- method_def = [
193
- "def #{method_prefix}#{method}(#{definition})", # def customer_name(*args, &block)
194
- " _ = #{to}", # _ = client
195
- " _.#{method}(#{definition})", # _.name(*args, &block)
196
- "rescue NoMethodError => e", # rescue NoMethodError => e
197
- " if _.nil? && e.name == :#{method}", # if _.nil? && e.name == :name
198
- " #{exception}", # # add helpful message to the exception
199
- " else", # else
200
- " raise", # raise
201
- " end", # end
202
- "end" # end
203
- ].join ';'
204
- end
181
+ exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
182
+
183
+ method_def = [
184
+ "def #{method_prefix}#{method}(#{definition})",
185
+ " _ = #{to}",
186
+ " if !_.nil? || nil.respond_to?(:#{method})",
187
+ " _.#{method}(#{definition})",
188
+ " else",
189
+ " #{exception unless allow_nil}",
190
+ " end",
191
+ "end"
192
+ ].join ';'
205
193
 
206
194
  module_eval(method_def, file, line)
207
195
  end
@@ -61,25 +61,7 @@ class Numeric
61
61
  end
62
62
  alias :fortnight :fortnights
63
63
 
64
- # Reads best without arguments: 10.minutes.ago
65
- def ago(time = ::Time.current)
66
- ActiveSupport::Deprecation.warn "Calling #ago or #until on a number (e.g. 5.ago) is deprecated and will be removed in the future, use 5.seconds.ago instead"
67
- time - self
68
- end
69
-
70
- # Reads best with argument: 10.minutes.until(time)
71
- alias :until :ago
72
-
73
- # Reads best with argument: 10.minutes.since(time)
74
- def since(time = ::Time.current)
75
- ActiveSupport::Deprecation.warn "Calling #since or #from_now on a number (e.g. 5.since) is deprecated and will be removed in the future, use 5.seconds.since instead"
76
- time + self
77
- end
78
-
79
- # Reads best without arguments: 10.minutes.from_now
80
- alias :from_now :since
81
-
82
- # Used with the standard time durations, like 1.hour.in_milliseconds --
64
+ # Used with the standard time durations, like 1.hour.in_milliseconds --
83
65
  # so we can feed them to JavaScript functions like getTime().
84
66
  def in_milliseconds
85
67
  self * 1000
@@ -2,6 +2,7 @@ require 'active_support/core_ext/object/acts_like'
2
2
  require 'active_support/core_ext/object/blank'
3
3
  require 'active_support/core_ext/object/duplicable'
4
4
  require 'active_support/core_ext/object/deep_dup'
5
+ require 'active_support/core_ext/object/itself'
5
6
  require 'active_support/core_ext/object/try'
6
7
  require 'active_support/core_ext/object/inclusion'
7
8