activesupport 3.2.22.5 → 4.0.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 (214) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +364 -135
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +6 -4
  5. data/lib/active_support/backtrace_cleaner.rb +33 -25
  6. data/lib/active_support/basic_object.rb +7 -17
  7. data/lib/active_support/benchmarkable.rb +19 -15
  8. data/lib/active_support/buffered_logger.rb +9 -113
  9. data/lib/active_support/cache/file_store.rb +14 -14
  10. data/lib/active_support/cache/mem_cache_store.rb +24 -30
  11. data/lib/active_support/cache/memory_store.rb +2 -0
  12. data/lib/active_support/cache/strategy/local_cache.rb +48 -37
  13. data/lib/active_support/cache.rb +228 -183
  14. data/lib/active_support/callbacks.rb +201 -253
  15. data/lib/active_support/concern.rb +16 -23
  16. data/lib/active_support/concurrency/latch.rb +27 -0
  17. data/lib/active_support/configurable.rb +69 -12
  18. data/lib/active_support/core_ext/array/access.rb +17 -9
  19. data/lib/active_support/core_ext/array/conversions.rb +115 -55
  20. data/lib/active_support/core_ext/array/extract_options.rb +2 -2
  21. data/lib/active_support/core_ext/array/grouping.rb +21 -22
  22. data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
  23. data/lib/active_support/core_ext/array/wrap.rb +13 -16
  24. data/lib/active_support/core_ext/array.rb +0 -1
  25. data/lib/active_support/core_ext/benchmark.rb +7 -0
  26. data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -24
  27. data/lib/active_support/core_ext/class/attribute.rb +40 -32
  28. data/lib/active_support/core_ext/class/attribute_accessors.rb +14 -12
  29. data/lib/active_support/core_ext/class/delegating_attributes.rb +15 -19
  30. data/lib/active_support/core_ext/class/subclasses.rb +11 -5
  31. data/lib/active_support/core_ext/date/calculations.rb +44 -187
  32. data/lib/active_support/core_ext/date/conversions.rb +16 -38
  33. data/lib/active_support/core_ext/date/zones.rb +25 -2
  34. data/lib/active_support/core_ext/date.rb +5 -0
  35. data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
  36. data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
  37. data/lib/active_support/core_ext/date_time/calculations.rb +77 -62
  38. data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
  39. data/lib/active_support/core_ext/date_time/zones.rb +11 -8
  40. data/lib/active_support/core_ext/date_time.rb +4 -0
  41. data/lib/active_support/core_ext/enumerable.rb +26 -73
  42. data/lib/active_support/core_ext/file/atomic.rb +27 -11
  43. data/lib/active_support/core_ext/file.rb +0 -1
  44. data/lib/active_support/core_ext/hash/conversions.rb +145 -79
  45. data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
  46. data/lib/active_support/core_ext/hash/diff.rb +5 -4
  47. data/lib/active_support/core_ext/hash/except.rb +1 -9
  48. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
  49. data/lib/active_support/core_ext/hash/keys.rb +108 -24
  50. data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
  51. data/lib/active_support/core_ext/hash/slice.rb +12 -12
  52. data/lib/active_support/core_ext/hash.rb +0 -1
  53. data/lib/active_support/core_ext/integer/inflections.rb +13 -1
  54. data/lib/active_support/core_ext/integer/time.rb +17 -12
  55. data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
  56. data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
  57. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
  58. data/lib/active_support/core_ext/load_error.rb +7 -5
  59. data/lib/active_support/core_ext/logger.rb +7 -23
  60. data/lib/active_support/core_ext/marshal.rb +21 -0
  61. data/lib/active_support/core_ext/module/aliasing.rb +8 -9
  62. data/lib/active_support/core_ext/module/anonymous.rb +2 -7
  63. data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
  64. data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
  65. data/lib/active_support/core_ext/module/delegation.rb +92 -49
  66. data/lib/active_support/core_ext/module/deprecation.rb +19 -3
  67. data/lib/active_support/core_ext/module/introspection.rb +17 -27
  68. data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
  69. data/lib/active_support/core_ext/module/remove_method.rb +1 -5
  70. data/lib/active_support/core_ext/module.rb +1 -3
  71. data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
  72. data/lib/active_support/core_ext/numeric/time.rb +6 -6
  73. data/lib/active_support/core_ext/numeric.rb +1 -0
  74. data/lib/active_support/core_ext/object/acts_like.rb +4 -4
  75. data/lib/active_support/core_ext/object/blank.rb +7 -23
  76. data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
  77. data/lib/active_support/core_ext/object/duplicable.rb +1 -30
  78. data/lib/active_support/core_ext/object/inclusion.rb +8 -7
  79. data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
  80. data/lib/active_support/core_ext/object/to_json.rb +8 -0
  81. data/lib/active_support/core_ext/object/to_param.rb +5 -2
  82. data/lib/active_support/core_ext/object/try.rb +46 -25
  83. data/lib/active_support/core_ext/object/with_options.rb +7 -8
  84. data/lib/active_support/core_ext/object.rb +1 -0
  85. data/lib/active_support/core_ext/proc.rb +3 -0
  86. data/lib/active_support/core_ext/range/conversions.rb +0 -2
  87. data/lib/active_support/core_ext/range/include_range.rb +3 -1
  88. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  89. data/lib/active_support/core_ext/range.rb +0 -2
  90. data/lib/active_support/core_ext/string/access.rb +95 -90
  91. data/lib/active_support/core_ext/string/conversions.rb +27 -38
  92. data/lib/active_support/core_ext/string/encoding.rb +6 -9
  93. data/lib/active_support/core_ext/string/filters.rb +24 -18
  94. data/lib/active_support/core_ext/string/indent.rb +43 -0
  95. data/lib/active_support/core_ext/string/inflections.rb +70 -60
  96. data/lib/active_support/core_ext/string/inquiry.rb +2 -2
  97. data/lib/active_support/core_ext/string/multibyte.rb +41 -64
  98. data/lib/active_support/core_ext/string/output_safety.rb +59 -51
  99. data/lib/active_support/core_ext/string/zones.rb +13 -0
  100. data/lib/active_support/core_ext/string.rb +2 -3
  101. data/lib/active_support/core_ext/struct.rb +6 -0
  102. data/lib/active_support/core_ext/thread.rb +74 -0
  103. data/lib/active_support/core_ext/time/calculations.rb +108 -184
  104. data/lib/active_support/core_ext/time/conversions.rb +27 -51
  105. data/lib/active_support/core_ext/time/marshal.rb +0 -27
  106. data/lib/active_support/core_ext/time/zones.rb +27 -17
  107. data/lib/active_support/core_ext/time.rb +5 -0
  108. data/lib/active_support/core_ext/uri.rb +13 -17
  109. data/lib/active_support/core_ext.rb +3 -2
  110. data/lib/active_support/dependencies/autoload.rb +47 -20
  111. data/lib/active_support/dependencies.rb +160 -141
  112. data/lib/active_support/deprecation/behaviors.rb +44 -30
  113. data/lib/active_support/deprecation/instance_delegator.rb +24 -0
  114. data/lib/active_support/deprecation/method_wrappers.rb +33 -18
  115. data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
  116. data/lib/active_support/deprecation/reporting.rb +40 -11
  117. data/lib/active_support/deprecation.rb +39 -14
  118. data/lib/active_support/descendants_tracker.rb +34 -19
  119. data/lib/active_support/duration.rb +6 -8
  120. data/lib/active_support/file_update_checker.rb +63 -47
  121. data/lib/active_support/gzip.rb +11 -5
  122. data/lib/active_support/hash_with_indifferent_access.rb +127 -42
  123. data/lib/active_support/i18n.rb +4 -0
  124. data/lib/active_support/i18n_railtie.rb +5 -22
  125. data/lib/active_support/inflections.rb +14 -12
  126. data/lib/active_support/inflector/inflections.rb +108 -71
  127. data/lib/active_support/inflector/methods.rb +181 -160
  128. data/lib/active_support/inflector/transliterate.rb +16 -17
  129. data/lib/active_support/json/decoding.rb +18 -17
  130. data/lib/active_support/json/encoding.rb +93 -39
  131. data/lib/active_support/json/variable.rb +10 -1
  132. data/lib/active_support/key_generator.rb +75 -0
  133. data/lib/active_support/lazy_load_hooks.rb +21 -19
  134. data/lib/active_support/locale/en.yml +100 -3
  135. data/lib/active_support/log_subscriber/test_helper.rb +18 -15
  136. data/lib/active_support/log_subscriber.rb +35 -52
  137. data/lib/active_support/logger.rb +57 -0
  138. data/lib/active_support/logger_silence.rb +24 -0
  139. data/lib/active_support/message_encryptor.rb +38 -35
  140. data/lib/active_support/message_verifier.rb +9 -15
  141. data/lib/active_support/multibyte/chars.rb +80 -333
  142. data/lib/active_support/multibyte/unicode.rb +74 -64
  143. data/lib/active_support/multibyte.rb +5 -28
  144. data/lib/active_support/notifications/fanout.rb +112 -18
  145. data/lib/active_support/notifications/instrumenter.rb +33 -14
  146. data/lib/active_support/notifications.rb +79 -26
  147. data/lib/active_support/number_helper.rb +637 -0
  148. data/lib/active_support/ordered_hash.rb +8 -190
  149. data/lib/active_support/ordered_options.rb +21 -23
  150. data/lib/active_support/per_thread_registry.rb +52 -0
  151. data/lib/active_support/proxy_object.rb +13 -0
  152. data/lib/active_support/rails.rb +27 -0
  153. data/lib/active_support/railtie.rb +12 -32
  154. data/lib/active_support/rescuable.rb +9 -4
  155. data/lib/active_support/string_inquirer.rb +13 -8
  156. data/lib/active_support/subscriber.rb +93 -0
  157. data/lib/active_support/tagged_logging.rb +51 -73
  158. data/lib/active_support/test_case.rb +46 -17
  159. data/lib/active_support/testing/assertions.rb +56 -26
  160. data/lib/active_support/testing/autorun.rb +5 -0
  161. data/lib/active_support/testing/constant_lookup.rb +54 -0
  162. data/lib/active_support/testing/declarative.rb +1 -1
  163. data/lib/active_support/testing/deprecation.rb +0 -19
  164. data/lib/active_support/testing/isolation.rb +29 -58
  165. data/lib/active_support/testing/pending.rb +5 -43
  166. data/lib/active_support/testing/setup_and_teardown.rb +6 -92
  167. data/lib/active_support/testing/tagged_logging.rb +25 -0
  168. data/lib/active_support/time.rb +6 -21
  169. data/lib/active_support/time_with_zone.rb +80 -43
  170. data/lib/active_support/values/time_zone.rb +81 -60
  171. data/lib/active_support/values/unicode_tables.dat +0 -0
  172. data/lib/active_support/version.rb +7 -6
  173. data/lib/active_support/xml_mini/jdom.rb +9 -11
  174. data/lib/active_support/xml_mini/libxml.rb +1 -2
  175. data/lib/active_support/xml_mini/libxmlsax.rb +2 -3
  176. data/lib/active_support/xml_mini/nokogiri.rb +1 -2
  177. data/lib/active_support/xml_mini/nokogirisax.rb +2 -3
  178. data/lib/active_support/xml_mini/rexml.rb +6 -8
  179. data/lib/active_support/xml_mini.rb +35 -17
  180. data/lib/active_support.rb +8 -21
  181. metadata +104 -72
  182. data/lib/active_support/base64.rb +0 -54
  183. data/lib/active_support/core_ext/array/random_access.rb +0 -30
  184. data/lib/active_support/core_ext/date/freeze.rb +0 -33
  185. data/lib/active_support/core_ext/exception.rb +0 -3
  186. data/lib/active_support/core_ext/file/path.rb +0 -5
  187. data/lib/active_support/core_ext/float/rounding.rb +0 -19
  188. data/lib/active_support/core_ext/float.rb +0 -1
  189. data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
  190. data/lib/active_support/core_ext/io.rb +0 -15
  191. data/lib/active_support/core_ext/module/method_names.rb +0 -14
  192. data/lib/active_support/core_ext/module/synchronization.rb +0 -45
  193. data/lib/active_support/core_ext/process/daemon.rb +0 -23
  194. data/lib/active_support/core_ext/process.rb +0 -1
  195. data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
  196. data/lib/active_support/core_ext/range/cover.rb +0 -3
  197. data/lib/active_support/core_ext/rexml.rb +0 -46
  198. data/lib/active_support/core_ext/string/interpolation.rb +0 -2
  199. data/lib/active_support/core_ext/string/xchar.rb +0 -18
  200. data/lib/active_support/core_ext/time/publicize_conversion_methods.rb +0 -10
  201. data/lib/active_support/memoizable.rb +0 -116
  202. data/lib/active_support/multibyte/exceptions.rb +0 -8
  203. data/lib/active_support/multibyte/utils.rb +0 -60
  204. data/lib/active_support/ruby/shim.rb +0 -22
  205. data/lib/active_support/security_utils.rb +0 -27
  206. data/lib/active_support/testing/mochaing.rb +0 -7
  207. data/lib/active_support/testing/performance/jruby.rb +0 -115
  208. data/lib/active_support/testing/performance/rubinius.rb +0 -113
  209. data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
  210. data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
  211. data/lib/active_support/testing/performance/ruby.rb +0 -152
  212. data/lib/active_support/testing/performance.rb +0 -317
  213. data/lib/active_support/time/autoload.rb +0 -5
  214. data/lib/active_support/whiny_nil.rb +0 -24
data/README.rdoc CHANGED
@@ -12,19 +12,21 @@ The latest version of Active Support can be installed with RubyGems:
12
12
 
13
13
  % [sudo] gem install activesupport
14
14
 
15
- Source code can be downloaded as part of the Rails project on GitHub
15
+ Source code can be downloaded as part of the Rails project on GitHub:
16
16
 
17
- * https://github.com/rails/rails/tree/3-2-stable/activesupport
17
+ * https://github.com/rails/rails/tree/master/activesupport
18
18
 
19
19
 
20
20
  == License
21
21
 
22
- Active Support is released under the MIT license.
22
+ Active Support is released under the MIT license:
23
+
24
+ * http://www.opensource.org/licenses/MIT
23
25
 
24
26
 
25
27
  == Support
26
28
 
27
- API documentation is at
29
+ API documentation is at:
28
30
 
29
31
  * http://api.rubyonrails.org
30
32
 
@@ -1,24 +1,29 @@
1
1
  module ActiveSupport
2
- # Backtraces often include many lines that are not relevant for the context under review. This makes it hard to find the
3
- # signal amongst the backtrace noise, and adds debugging time. With a BacktraceCleaner, filters and silencers are used to
4
- # remove the noisy lines, so that only the most relevant lines remain.
2
+ # Backtraces often include many lines that are not relevant for the context
3
+ # under review. This makes it hard to find the signal amongst the backtrace
4
+ # noise, and adds debugging time. With a BacktraceCleaner, filters and
5
+ # silencers are used to remove the noisy lines, so that only the most relevant
6
+ # lines remain.
5
7
  #
6
- # Filters are used to modify lines of data, while silencers are used to remove lines entirely. The typical filter use case
7
- # is to remove lengthy path information from the start of each line, and view file paths relevant to the app directory
8
- # instead of the file system root. The typical silencer use case is to exclude the output of a noisy library from the
9
- # backtrace, so that you can focus on the rest.
10
- #
11
- # ==== Example:
8
+ # Filters are used to modify lines of data, while silencers are used to remove
9
+ # lines entirely. The typical filter use case is to remove lengthy path
10
+ # information from the start of each line, and view file paths relevant to the
11
+ # app directory instead of the file system root. The typical silencer use case
12
+ # is to exclude the output of a noisy library from the backtrace, so that you
13
+ # can focus on the rest.
12
14
  #
13
15
  # bc = BacktraceCleaner.new
14
16
  # bc.add_filter { |line| line.gsub(Rails.root, '') }
15
17
  # bc.add_silencer { |line| line =~ /mongrel|rubygems/ }
16
18
  # bc.clean(exception.backtrace) # will strip the Rails.root prefix and skip any lines from mongrel or rubygems
17
19
  #
18
- # To reconfigure an existing BacktraceCleaner (like the default one in Rails) and show as much data as possible, you can
19
- # always call <tt>BacktraceCleaner#remove_silencers!</tt>, which will restore the backtrace to a pristine state. If you
20
- # need to reconfigure an existing BacktraceCleaner so that it does not filter or modify the paths of any lines of the
21
- # backtrace, you can call BacktraceCleaner#remove_filters! These two methods will give you a completely untouched backtrace.
20
+ # To reconfigure an existing BacktraceCleaner (like the default one in Rails)
21
+ # and show as much data as possible, you can always call
22
+ # <tt>BacktraceCleaner#remove_silencers!</tt>, which will restore the
23
+ # backtrace to a pristine state. If you need to reconfigure an existing
24
+ # BacktraceCleaner so that it does not filter or modify the paths of any lines
25
+ # of the backtrace, you can call BacktraceCleaner#remove_filters! These two
26
+ # methods will give you a completely untouched backtrace.
22
27
  #
23
28
  # Inspired by the Quiet Backtrace gem by Thoughtbot.
24
29
  class BacktraceCleaner
@@ -26,9 +31,10 @@ module ActiveSupport
26
31
  @filters, @silencers = [], []
27
32
  end
28
33
 
29
- # Returns the backtrace after all filters and silencers have been run against it. Filters run first, then silencers.
34
+ # Returns the backtrace after all filters and silencers have been run
35
+ # against it. Filters run first, then silencers.
30
36
  def clean(backtrace, kind = :silent)
31
- filtered = filter(backtrace)
37
+ filtered = filter_backtrace(backtrace)
32
38
 
33
39
  case kind
34
40
  when :silent
@@ -39,10 +45,10 @@ module ActiveSupport
39
45
  filtered
40
46
  end
41
47
  end
48
+ alias :filter :clean
42
49
 
43
- # Adds a filter from the block provided. Each line in the backtrace will be mapped against this filter.
44
- #
45
- # Example:
50
+ # Adds a filter from the block provided. Each line in the backtrace will be
51
+ # mapped against this filter.
46
52
  #
47
53
  # # Will turn "/my/rails/root/app/models/person.rb" into "/app/models/person.rb"
48
54
  # backtrace_cleaner.add_filter { |line| line.gsub(Rails.root, '') }
@@ -50,10 +56,8 @@ module ActiveSupport
50
56
  @filters << block
51
57
  end
52
58
 
53
- # Adds a silencer from the block provided. If the silencer returns true for a given line, it will be excluded from
54
- # the clean backtrace.
55
- #
56
- # Example:
59
+ # Adds a silencer from the block provided. If the silencer returns +true+
60
+ # for a given line, it will be excluded from the clean backtrace.
57
61
  #
58
62
  # # Will reject all lines that include the word "mongrel", like "/gems/mongrel/server.rb" or "/app/my_mongrel_server/rb"
59
63
  # backtrace_cleaner.add_silencer { |line| line =~ /mongrel/ }
@@ -61,18 +65,22 @@ module ActiveSupport
61
65
  @silencers << block
62
66
  end
63
67
 
64
- # Will remove all silencers, but leave in the filters. This is useful if your context of debugging suddenly expands as
65
- # you suspect a bug in one of the libraries you use.
68
+ # Will remove all silencers, but leave in the filters. This is useful if
69
+ # your context of debugging suddenly expands as you suspect a bug in one of
70
+ # the libraries you use.
66
71
  def remove_silencers!
67
72
  @silencers = []
68
73
  end
69
74
 
75
+ # Removes all filters, but leaves in silencers. Useful if you suddenly
76
+ # need to see entire filepaths in the backtrace that you had already
77
+ # filtered out.
70
78
  def remove_filters!
71
79
  @filters = []
72
80
  end
73
81
 
74
82
  private
75
- def filter(backtrace)
83
+ def filter_backtrace(backtrace)
76
84
  @filters.each do |f|
77
85
  backtrace = backtrace.map { |line| f.call(line) }
78
86
  end
@@ -1,21 +1,11 @@
1
- module ActiveSupport
2
- if defined? ::BasicObject
3
- # A class with no predefined methods that behaves similarly to Builder's
4
- # BlankSlate. Used for proxy classes.
5
- class BasicObject < ::BasicObject
6
- undef_method :==
7
- undef_method :equal?
1
+ require 'active_support/deprecation'
2
+ require 'active_support/proxy_object'
8
3
 
9
- # Let ActiveSupport::BasicObject at least raise exceptions.
10
- def raise(*args)
11
- ::Object.send(:raise, *args)
12
- end
13
- end
14
- else
15
- class BasicObject #:nodoc:
16
- instance_methods.each do |m|
17
- undef_method(m) if m.to_s !~ /(?:^__|^nil\?$|^send$|^object_id$)/
18
- end
4
+ module ActiveSupport
5
+ class BasicObject < ProxyObject # :nodoc:
6
+ def self.inherited(*)
7
+ ::ActiveSupport::Deprecation.warn 'ActiveSupport::BasicObject is deprecated! Use ActiveSupport::ProxyObject instead.'
8
+ super
19
9
  end
20
10
  end
21
11
  end
@@ -3,30 +3,33 @@ require 'active_support/core_ext/hash/keys'
3
3
 
4
4
  module ActiveSupport
5
5
  module Benchmarkable
6
- # Allows you to measure the execution time of a block in a template and records the result to
7
- # the log. Wrap this block around expensive operations or possible bottlenecks to get a time
8
- # reading for the operation. For example, let's say you thought your file processing method
9
- # was taking too long; you could wrap it in a benchmark block.
6
+ # Allows you to measure the execution time of a block in a template and
7
+ # records the result to the log. Wrap this block around expensive operations
8
+ # or possible bottlenecks to get a time reading for the operation. For
9
+ # example, let's say you thought your file processing method was taking too
10
+ # long; you could wrap it in a benchmark block.
10
11
  #
11
- # <% benchmark "Process data files" do %>
12
+ # <% benchmark 'Process data files' do %>
12
13
  # <%= expensive_files_operation %>
13
14
  # <% end %>
14
15
  #
15
- # That would add something like "Process data files (345.2ms)" to the log, which you can then
16
- # use to compare timings when optimizing your code.
16
+ # That would add something like "Process data files (345.2ms)" to the log,
17
+ # which you can then use to compare timings when optimizing your code.
17
18
  #
18
- # You may give an optional logger level (:debug, :info, :warn, :error) as the :level option.
19
- # The default logger level value is :info.
19
+ # You may give an optional logger level (<tt>:debug</tt>, <tt>:info</tt>,
20
+ # <tt>:warn</tt>, <tt>:error</tt>) as the <tt>:level</tt> option. The
21
+ # default logger level value is <tt>:info</tt>.
20
22
  #
21
- # <% benchmark "Low-level files", :level => :debug do %>
23
+ # <% benchmark 'Low-level files', level: :debug do %>
22
24
  # <%= lowlevel_files_operation %>
23
25
  # <% end %>
24
26
  #
25
- # Finally, you can pass true as the third argument to silence all log activity (other than the
26
- # timing information) from inside the block. This is great for boiling down a noisy block to
27
- # just a single statement that produces one log line:
27
+ # Finally, you can pass true as the third argument to silence all log
28
+ # activity (other than the timing information) from inside the block. This
29
+ # is great for boiling down a noisy block to just a single statement that
30
+ # produces one log line:
28
31
  #
29
- # <% benchmark "Process data files", :level => :info, :silence => true do %>
32
+ # <% benchmark 'Process data files', level: :info, silence: true do %>
30
33
  # <%= expensive_and_chatty_files_operation %>
31
34
  # <% end %>
32
35
  def benchmark(message = "Benchmarking", options = {})
@@ -44,8 +47,9 @@ module ActiveSupport
44
47
  end
45
48
 
46
49
  # Silence the logger during the execution of the block.
47
- #
48
50
  def silence
51
+ message = "ActiveSupport::Benchmarkable#silence is deprecated. It will be removed from Rails 4.1."
52
+ ActiveSupport::Deprecation.warn message
49
53
  old_logger_level, logger.level = logger.level, ::Logger::ERROR if logger
50
54
  yield
51
55
  ensure
@@ -1,125 +1,21 @@
1
- require 'thread'
2
- require 'logger'
3
- require 'active_support/core_ext/logger'
4
- require 'active_support/core_ext/class/attribute_accessors'
5
1
  require 'active_support/deprecation'
6
- require 'fileutils'
2
+ require 'active_support/logger'
7
3
 
8
4
  module ActiveSupport
9
- # Inspired by the buffered logger idea by Ezra
10
- class BufferedLogger
11
- module Severity
12
- DEBUG = 0
13
- INFO = 1
14
- WARN = 2
15
- ERROR = 3
16
- FATAL = 4
17
- UNKNOWN = 5
18
- end
19
- include Severity
20
-
21
- MAX_BUFFER_SIZE = 1000
22
-
23
- ##
24
- # :singleton-method:
25
- # Set to false to disable the silencer
26
- cattr_accessor :silencer
27
- self.silencer = true
28
-
29
- # Silences the logger for the duration of the block.
30
- def silence(temporary_level = ERROR)
31
- if silencer
32
- begin
33
- logger = self.class.new @log_dest.dup, temporary_level
34
- yield logger
35
- ensure
36
- logger.close
37
- end
38
- else
39
- yield self
40
- end
41
- end
42
- deprecate :silence
43
-
44
- attr_reader :auto_flushing
45
- deprecate :auto_flushing
46
-
47
- def initialize(log, level = DEBUG)
48
- @log_dest = log
49
-
50
- unless log.respond_to?(:write)
51
- unless File.exist?(File.dirname(log))
52
- ActiveSupport::Deprecation.warn(<<-eowarn)
53
- Automatic directory creation for '#{log}' is deprecated. Please make sure the directory for your log file exists before creating the logger.
54
- eowarn
55
- FileUtils.mkdir_p(File.dirname(log))
56
- end
57
- end
58
-
59
- @log = open_logfile log
60
- self.level = level
61
- end
62
-
63
- def open_log(log, mode)
64
- open(log, mode).tap do |open_log|
65
- open_log.set_encoding(Encoding::BINARY) if open_log.respond_to?(:set_encoding)
66
- open_log.sync = true
67
- end
68
- end
69
- deprecate :open_log
70
-
71
- def level
72
- @log.level
73
- end
74
-
75
- def level=(l)
76
- @log.level = l
77
- end
5
+ class BufferedLogger < Logger
78
6
 
79
- def add(severity, message = nil, progname = nil, &block)
80
- @log.add(severity, message, progname, &block)
81
- end
82
-
83
- # Dynamically add methods such as:
84
- # def info
85
- # def warn
86
- # def debug
87
- Severity.constants.each do |severity|
88
- class_eval <<-EOT, __FILE__, __LINE__ + 1
89
- def #{severity.downcase}(message = nil, progname = nil, &block) # def debug(message = nil, progname = nil, &block)
90
- add(#{severity}, message, progname, &block) # add(DEBUG, message, progname, &block)
91
- end # end
92
-
93
- def #{severity.downcase}? # def debug?
94
- #{severity} >= level # DEBUG >= level
95
- end # end
96
- EOT
97
- end
98
-
99
- # Set the auto-flush period. Set to true to flush after every log message,
100
- # to an integer to flush every N messages, or to false, nil, or zero to
101
- # never auto-flush. If you turn auto-flushing off, be sure to regularly
102
- # flush the log yourself -- it will eat up memory until you do.
103
- def auto_flushing=(period)
104
- end
105
- deprecate :auto_flushing=
106
-
107
- def flush
108
- end
109
- deprecate :flush
110
-
111
- def respond_to?(method, include_private = false)
112
- return false if method.to_s == "flush"
7
+ def initialize(*args)
8
+ self.class._deprecation_warning
113
9
  super
114
10
  end
115
11
 
116
- def close
117
- @log.close
12
+ def self.inherited(*)
13
+ _deprecation_warning
14
+ super
118
15
  end
119
16
 
120
- private
121
- def open_logfile(log)
122
- Logger.new log
17
+ def self._deprecation_warning
18
+ ::ActiveSupport::Deprecation.warn 'ActiveSupport::BufferedLogger is deprecated! Use ActiveSupport::Logger instead.'
123
19
  end
124
20
  end
125
21
  end
@@ -1,7 +1,7 @@
1
+ require 'active_support/core_ext/marshal'
1
2
  require 'active_support/core_ext/file/atomic'
2
3
  require 'active_support/core_ext/string/conversions'
3
- require 'active_support/core_ext/object/inclusion'
4
- require 'rack/utils'
4
+ require 'uri/common'
5
5
 
6
6
  module ActiveSupport
7
7
  module Cache
@@ -13,7 +13,7 @@ module ActiveSupport
13
13
  attr_reader :cache_path
14
14
 
15
15
  DIR_FORMATTER = "%03X"
16
- FILENAME_MAX_SIZE = 230 # max filename size on file system is 255, minus room for timestamp and random characters appended by Tempfile (used by atomic write)
16
+ FILENAME_MAX_SIZE = 228 # max filename size on file system is 255, minus room for timestamp and random characters appended by Tempfile (used by atomic write)
17
17
  EXCLUDED_DIRS = ['.', '..'].freeze
18
18
 
19
19
  def initialize(cache_path, options = nil)
@@ -23,14 +23,13 @@ module ActiveSupport
23
23
  end
24
24
 
25
25
  def clear(options = nil)
26
- root_dirs = Dir.entries(cache_path).reject{|f| f.in?(EXCLUDED_DIRS)}
26
+ root_dirs = Dir.entries(cache_path).reject {|f| (EXCLUDED_DIRS + [".gitkeep"]).include?(f)}
27
27
  FileUtils.rm_r(root_dirs.collect{|f| File.join(cache_path, f)})
28
28
  end
29
29
 
30
30
  def cleanup(options = nil)
31
31
  options = merged_options(options)
32
- search_dir(cache_path) do |fname|
33
- key = file_path_key(fname)
32
+ each_key(options) do |key|
34
33
  entry = read_entry(key, options)
35
34
  delete_entry(key, options) if entry && entry.expired?
36
35
  end
@@ -82,7 +81,8 @@ module ActiveSupport
82
81
  if File.exist?(file_name)
83
82
  File.open(file_name) { |f| Marshal.load(f) }
84
83
  end
85
- rescue
84
+ rescue => e
85
+ logger.error("FileStoreError (#{e}): #{e.message}") if logger
86
86
  nil
87
87
  end
88
88
 
@@ -127,7 +127,7 @@ module ActiveSupport
127
127
 
128
128
  # Translate a key into a file path.
129
129
  def key_file_path(key)
130
- fname = Rack::Utils.escape(key)
130
+ fname = URI.encode_www_form_component(key)
131
131
  hash = Zlib.adler32(fname)
132
132
  hash, dir_1 = hash.divmod(0x1000)
133
133
  dir_2 = hash.modulo(0x1000)
@@ -144,15 +144,15 @@ module ActiveSupport
144
144
 
145
145
  # Translate a file path into a key.
146
146
  def file_path_key(path)
147
- fname = path[cache_path.size, path.size].split(File::SEPARATOR, 4).last
148
- Rack::Utils.unescape(fname)
147
+ fname = path[cache_path.to_s.size..-1].split(File::SEPARATOR, 4).last
148
+ URI.decode_www_form_component(fname, Encoding::UTF_8)
149
149
  end
150
150
 
151
151
  # Delete empty directories in the cache.
152
152
  def delete_empty_directories(dir)
153
- return if dir == cache_path
154
- if Dir.entries(dir).reject{|f| f.in?(EXCLUDED_DIRS)}.empty?
155
- File.delete(dir) rescue nil
153
+ return if File.realpath(dir) == File.realpath(cache_path)
154
+ if Dir.entries(dir).reject {|f| EXCLUDED_DIRS.include?(f)}.empty?
155
+ Dir.delete(dir) rescue nil
156
156
  delete_empty_directories(File.dirname(dir))
157
157
  end
158
158
  end
@@ -165,7 +165,7 @@ module ActiveSupport
165
165
  def search_dir(dir, &callback)
166
166
  return if !File.exist?(dir)
167
167
  Dir.foreach(dir) do |d|
168
- next if d.in?(EXCLUDED_DIRS)
168
+ next if EXCLUDED_DIRS.include?(d)
169
169
  name = File.join(dir, d)
170
170
  if File.directory?(name)
171
171
  search_dir(name, &callback)
@@ -1,12 +1,13 @@
1
1
  begin
2
- require 'memcache'
2
+ require 'dalli'
3
3
  rescue LoadError => e
4
- $stderr.puts "You don't have memcache-client installed in your application. Please add it to your Gemfile and run bundle install"
4
+ $stderr.puts "You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install"
5
5
  raise e
6
6
  end
7
7
 
8
8
  require 'digest/md5'
9
- require 'active_support/core_ext/string/encoding'
9
+ require 'active_support/core_ext/marshal'
10
+ require 'active_support/core_ext/array/extract_options'
10
11
 
11
12
  module ActiveSupport
12
13
  module Cache
@@ -23,21 +24,13 @@ module ActiveSupport
23
24
  # MemCacheStore implements the Strategy::LocalCache strategy which implements
24
25
  # an in-memory cache inside of a block.
25
26
  class MemCacheStore < Store
26
- module Response # :nodoc:
27
- STORED = "STORED\r\n"
28
- NOT_STORED = "NOT_STORED\r\n"
29
- EXISTS = "EXISTS\r\n"
30
- NOT_FOUND = "NOT_FOUND\r\n"
31
- DELETED = "DELETED\r\n"
32
- end
33
-
34
27
  ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/n
35
28
 
36
29
  def self.build_mem_cache(*addresses)
37
30
  addresses = addresses.flatten
38
31
  options = addresses.extract_options!
39
32
  addresses = ["localhost:11211"] if addresses.empty?
40
- MemCache.new(addresses, options)
33
+ Dalli::Client.new(addresses, options)
41
34
  end
42
35
 
43
36
  # Creates a new MemCacheStore object, with the given memcached server
@@ -91,11 +84,11 @@ module ActiveSupport
91
84
  # to zero.
92
85
  def increment(name, amount = 1, options = nil) # :nodoc:
93
86
  options = merged_options(options)
94
- response = instrument(:increment, name, :amount => amount) do
87
+ instrument(:increment, name, :amount => amount) do
95
88
  @data.incr(escape_key(namespaced_key(name, options)), amount)
96
89
  end
97
- response == Response::NOT_FOUND ? nil : response.to_i
98
- rescue MemCache::MemCacheError
90
+ rescue Dalli::DalliError
91
+ logger.error("DalliError (#{e}): #{e.message}") if logger
99
92
  nil
100
93
  end
101
94
 
@@ -105,11 +98,11 @@ module ActiveSupport
105
98
  # to zero.
106
99
  def decrement(name, amount = 1, options = nil) # :nodoc:
107
100
  options = merged_options(options)
108
- response = instrument(:decrement, name, :amount => amount) do
101
+ instrument(:decrement, name, :amount => amount) do
109
102
  @data.decr(escape_key(namespaced_key(name, options)), amount)
110
103
  end
111
- response == Response::NOT_FOUND ? nil : response.to_i
112
- rescue MemCache::MemCacheError
104
+ rescue Dalli::DalliError
105
+ logger.error("DalliError (#{e}): #{e.message}") if logger
113
106
  nil
114
107
  end
115
108
 
@@ -117,6 +110,9 @@ module ActiveSupport
117
110
  # be used with care when shared cache is being used.
118
111
  def clear(options = nil)
119
112
  @data.flush_all
113
+ rescue Dalli::DalliError => e
114
+ logger.error("DalliError (#{e}): #{e.message}") if logger
115
+ nil
120
116
  end
121
117
 
122
118
  # Get the statistics from the memcached servers.
@@ -127,9 +123,9 @@ module ActiveSupport
127
123
  protected
128
124
  # Read an entry from the cache.
129
125
  def read_entry(key, options) # :nodoc:
130
- deserialize_entry(@data.get(escape_key(key), true))
131
- rescue MemCache::MemCacheError => e
132
- logger.error("MemCacheError (#{e}): #{e.message}") if logger
126
+ deserialize_entry(@data.get(escape_key(key), options))
127
+ rescue Dalli::DalliError => e
128
+ logger.error("DalliError (#{e}): #{e.message}") if logger
133
129
  nil
134
130
  end
135
131
 
@@ -142,19 +138,17 @@ module ActiveSupport
142
138
  # Set the memcache expire a few minutes in the future to support race condition ttls on read
143
139
  expires_in += 5.minutes
144
140
  end
145
- response = @data.send(method, escape_key(key), value, expires_in, options[:raw])
146
- response == Response::STORED
147
- rescue MemCache::MemCacheError => e
148
- logger.error("MemCacheError (#{e}): #{e.message}") if logger
141
+ @data.send(method, escape_key(key), value, expires_in, options)
142
+ rescue Dalli::DalliError => e
143
+ logger.error("DalliError (#{e}): #{e.message}") if logger
149
144
  false
150
145
  end
151
146
 
152
147
  # Delete an entry from the cache.
153
148
  def delete_entry(key, options) # :nodoc:
154
- response = @data.delete(escape_key(key))
155
- response == Response::DELETED
156
- rescue MemCache::MemCacheError => e
157
- logger.error("MemCacheError (#{e}): #{e.message}") if logger
149
+ @data.delete(escape_key(key))
150
+ rescue Dalli::DalliError => e
151
+ logger.error("DalliError (#{e}): #{e.message}") if logger
158
152
  false
159
153
  end
160
154
 
@@ -165,7 +159,7 @@ module ActiveSupport
165
159
  # characters properly.
166
160
  def escape_key(key)
167
161
  key = key.to_s.dup
168
- key = key.force_encoding("BINARY") if key.encoding_aware?
162
+ key = key.force_encoding(Encoding::ASCII_8BIT)
169
163
  key = key.gsub(ESCAPE_KEY_CHARS){ |match| "%#{match.getbyte(0).to_s(16).upcase}" }
170
164
  key = "#{key[0, 213]}:md5:#{Digest::MD5.hexdigest(key)}" if key.size > 250
171
165
  key
@@ -135,8 +135,10 @@ module ActiveSupport
135
135
  end
136
136
 
137
137
  def write_entry(key, entry, options) # :nodoc:
138
+ entry.dup_value!
138
139
  synchronize do
139
140
  old_entry = @data[key]
141
+ return false if @data.key?(key) && options[:unless_exist]
140
142
  @cache_size -= old_entry.size if old_entry
141
143
  @cache_size += entry.size
142
144
  @key_access[key] = Time.now.to_f