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
@@ -4,7 +4,7 @@ require 'active_support/inflector/transliterate'
4
4
  # String inflections define new methods on the String class to transform names for different purposes.
5
5
  # For instance, you can figure out the name of a table from the name of a class.
6
6
  #
7
- # "ScaleScore".tableize # => "scale_scores"
7
+ # 'ScaleScore'.tableize # => "scale_scores"
8
8
  #
9
9
  class String
10
10
  # Returns the plural form of the word in the string.
@@ -13,43 +13,55 @@ class String
13
13
  # the singular form will be returned if <tt>count == 1</tt>.
14
14
  # For any other value of +count+ the plural will be returned.
15
15
  #
16
- # ==== Examples
17
- # "post".pluralize # => "posts"
18
- # "octopus".pluralize # => "octopi"
19
- # "sheep".pluralize # => "sheep"
20
- # "words".pluralize # => "words"
21
- # "the blue mailman".pluralize # => "the blue mailmen"
22
- # "CamelOctopus".pluralize # => "CamelOctopi"
23
- # "apple".pluralize(1) # => "apple"
24
- # "apple".pluralize(2) # => "apples"
25
- def pluralize(count = nil)
16
+ # If the optional parameter +locale+ is specified,
17
+ # the word will be pluralized as a word of that language.
18
+ # By default, this parameter is set to <tt>:en</tt>.
19
+ # You must define your own inflection rules for languages other than English.
20
+ #
21
+ # 'post'.pluralize # => "posts"
22
+ # 'octopus'.pluralize # => "octopi"
23
+ # 'sheep'.pluralize # => "sheep"
24
+ # 'words'.pluralize # => "words"
25
+ # 'the blue mailman'.pluralize # => "the blue mailmen"
26
+ # 'CamelOctopus'.pluralize # => "CamelOctopi"
27
+ # 'apple'.pluralize(1) # => "apple"
28
+ # 'apple'.pluralize(2) # => "apples"
29
+ # 'ley'.pluralize(:es) # => "leyes"
30
+ # 'ley'.pluralize(1, :es) # => "ley"
31
+ def pluralize(count = nil, locale = :en)
32
+ locale = count if count.is_a?(Symbol)
26
33
  if count == 1
27
34
  self
28
35
  else
29
- ActiveSupport::Inflector.pluralize(self)
36
+ ActiveSupport::Inflector.pluralize(self, locale)
30
37
  end
31
38
  end
32
39
 
33
40
  # The reverse of +pluralize+, returns the singular form of a word in a string.
34
41
  #
35
- # "posts".singularize # => "post"
36
- # "octopi".singularize # => "octopus"
37
- # "sheep".singularize # => "sheep"
38
- # "word".singularize # => "word"
39
- # "the blue mailmen".singularize # => "the blue mailman"
40
- # "CamelOctopi".singularize # => "CamelOctopus"
41
- def singularize
42
- ActiveSupport::Inflector.singularize(self)
42
+ # If the optional parameter +locale+ is specified,
43
+ # the word will be singularized as a word of that language.
44
+ # By default, this parameter is set to <tt>:en</tt>.
45
+ # You must define your own inflection rules for languages other than English.
46
+ #
47
+ # 'posts'.singularize # => "post"
48
+ # 'octopi'.singularize # => "octopus"
49
+ # 'sheep'.singularize # => "sheep"
50
+ # 'word'.singularize # => "word"
51
+ # 'the blue mailmen'.singularize # => "the blue mailman"
52
+ # 'CamelOctopi'.singularize # => "CamelOctopus"
53
+ # 'leyes'.singularize(:es) # => "ley"
54
+ def singularize(locale = :en)
55
+ ActiveSupport::Inflector.singularize(self, locale)
43
56
  end
44
57
 
45
58
  # +constantize+ tries to find a declared constant with the name specified
46
59
  # in the string. It raises a NameError when the name is not in CamelCase
47
60
  # or is not initialized. See ActiveSupport::Inflector.constantize
48
61
  #
49
- # Examples
50
- # "Module".constantize # => Module
51
- # "Class".constantize # => Class
52
- # "blargle".constantize # => NameError: wrong constant name blargle
62
+ # 'Module'.constantize # => Module
63
+ # 'Class'.constantize # => Class
64
+ # 'blargle'.constantize # => NameError: wrong constant name blargle
53
65
  def constantize
54
66
  ActiveSupport::Inflector.constantize(self)
55
67
  end
@@ -58,10 +70,9 @@ class String
58
70
  # in the string. It returns nil when the name is not in CamelCase
59
71
  # or is not initialized. See ActiveSupport::Inflector.safe_constantize
60
72
  #
61
- # Examples
62
- # "Module".safe_constantize # => Module
63
- # "Class".safe_constantize # => Class
64
- # "blargle".safe_constantize # => nil
73
+ # 'Module'.safe_constantize # => Module
74
+ # 'Class'.safe_constantize # => Class
75
+ # 'blargle'.safe_constantize # => nil
65
76
  def safe_constantize
66
77
  ActiveSupport::Inflector.safe_constantize(self)
67
78
  end
@@ -71,14 +82,16 @@ class String
71
82
  #
72
83
  # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
73
84
  #
74
- # "active_record".camelize # => "ActiveRecord"
75
- # "active_record".camelize(:lower) # => "activeRecord"
76
- # "active_record/errors".camelize # => "ActiveRecord::Errors"
77
- # "active_record/errors".camelize(:lower) # => "activeRecord::Errors"
85
+ # 'active_record'.camelize # => "ActiveRecord"
86
+ # 'active_record'.camelize(:lower) # => "activeRecord"
87
+ # 'active_record/errors'.camelize # => "ActiveRecord::Errors"
88
+ # 'active_record/errors'.camelize(:lower) # => "activeRecord::Errors"
78
89
  def camelize(first_letter = :upper)
79
90
  case first_letter
80
- when :upper then ActiveSupport::Inflector.camelize(self, true)
81
- when :lower then ActiveSupport::Inflector.camelize(self, false)
91
+ when :upper
92
+ ActiveSupport::Inflector.camelize(self, true)
93
+ when :lower
94
+ ActiveSupport::Inflector.camelize(self, false)
82
95
  end
83
96
  end
84
97
  alias_method :camelcase, :camelize
@@ -89,8 +102,8 @@ class String
89
102
  #
90
103
  # +titleize+ is also aliased as +titlecase+.
91
104
  #
92
- # "man from the boondocks".titleize # => "Man From The Boondocks"
93
- # "x-men: the last stand".titleize # => "X Men: The Last Stand"
105
+ # 'man from the boondocks'.titleize # => "Man From The Boondocks"
106
+ # 'x-men: the last stand'.titleize # => "X Men: The Last Stand"
94
107
  def titleize
95
108
  ActiveSupport::Inflector.titleize(self)
96
109
  end
@@ -100,23 +113,23 @@ class String
100
113
  #
101
114
  # +underscore+ will also change '::' to '/' to convert namespaces to paths.
102
115
  #
103
- # "ActiveModel".underscore # => "active_model"
104
- # "ActiveModel::Errors".underscore # => "active_model/errors"
116
+ # 'ActiveModel'.underscore # => "active_model"
117
+ # 'ActiveModel::Errors'.underscore # => "active_model/errors"
105
118
  def underscore
106
119
  ActiveSupport::Inflector.underscore(self)
107
120
  end
108
121
 
109
122
  # Replaces underscores with dashes in the string.
110
123
  #
111
- # "puni_puni" # => "puni-puni"
124
+ # 'puni_puni'.dasherize # => "puni-puni"
112
125
  def dasherize
113
126
  ActiveSupport::Inflector.dasherize(self)
114
127
  end
115
128
 
116
129
  # Removes the module part from the constant expression in the string.
117
130
  #
118
- # "ActiveRecord::CoreExtensions::String::Inflections".demodulize # => "Inflections"
119
- # "Inflections".demodulize # => "Inflections"
131
+ # 'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
132
+ # 'Inflections'.demodulize # => "Inflections"
120
133
  #
121
134
  # See also +deconstantize+.
122
135
  def demodulize
@@ -125,11 +138,11 @@ class String
125
138
 
126
139
  # Removes the rightmost segment from the constant expression in the string.
127
140
  #
128
- # "Net::HTTP".deconstantize # => "Net"
129
- # "::Net::HTTP".deconstantize # => "::Net"
130
- # "String".deconstantize # => ""
131
- # "::String".deconstantize # => ""
132
- # "".deconstantize # => ""
141
+ # 'Net::HTTP'.deconstantize # => "Net"
142
+ # '::Net::HTTP'.deconstantize # => "::Net"
143
+ # 'String'.deconstantize # => ""
144
+ # '::String'.deconstantize # => ""
145
+ # ''.deconstantize # => ""
133
146
  #
134
147
  # See also +demodulize+.
135
148
  def deconstantize
@@ -138,8 +151,6 @@ class String
138
151
 
139
152
  # Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
140
153
  #
141
- # ==== Examples
142
- #
143
154
  # class Person
144
155
  # def to_param
145
156
  # "#{id}-#{name.parameterize}"
@@ -158,9 +169,9 @@ class String
158
169
  # Creates the name of a table like Rails does for models to table names. This method
159
170
  # uses the +pluralize+ method on the last word in the string.
160
171
  #
161
- # "RawScaledScorer".tableize # => "raw_scaled_scorers"
162
- # "egg_and_ham".tableize # => "egg_and_hams"
163
- # "fancyCategory".tableize # => "fancy_categories"
172
+ # 'RawScaledScorer'.tableize # => "raw_scaled_scorers"
173
+ # 'egg_and_ham'.tableize # => "egg_and_hams"
174
+ # 'fancyCategory'.tableize # => "fancy_categories"
164
175
  def tableize
165
176
  ActiveSupport::Inflector.tableize(self)
166
177
  end
@@ -169,12 +180,12 @@ class String
169
180
  # Note that this returns a string and not a class. (To convert to an actual class
170
181
  # follow +classify+ with +constantize+.)
171
182
  #
172
- # "egg_and_hams".classify # => "EggAndHam"
173
- # "posts".classify # => "Post"
183
+ # 'egg_and_hams'.classify # => "EggAndHam"
184
+ # 'posts'.classify # => "Post"
174
185
  #
175
186
  # Singular names are not handled correctly.
176
187
  #
177
- # "business".classify # => "Busines"
188
+ # 'business'.classify # => "Busines"
178
189
  def classify
179
190
  ActiveSupport::Inflector.classify(self)
180
191
  end
@@ -182,8 +193,8 @@ class String
182
193
  # Capitalizes the first word, turns underscores into spaces, and strips '_id'.
183
194
  # Like +titleize+, this is meant for creating pretty output.
184
195
  #
185
- # "employee_salary" # => "Employee salary"
186
- # "author_id" # => "Author"
196
+ # 'employee_salary'.humanize # => "Employee salary"
197
+ # 'author_id'.humanize # => "Author"
187
198
  def humanize
188
199
  ActiveSupport::Inflector.humanize(self)
189
200
  end
@@ -192,10 +203,9 @@ class String
192
203
  # +separate_class_name_and_id_with_underscore+ sets whether
193
204
  # the method should put '_' between the name and 'id'.
194
205
  #
195
- # Examples
196
- # "Message".foreign_key # => "message_id"
197
- # "Message".foreign_key(false) # => "messageid"
198
- # "Admin::Post".foreign_key # => "post_id"
206
+ # 'Message'.foreign_key # => "message_id"
207
+ # 'Message'.foreign_key(false) # => "messageid"
208
+ # 'Admin::Post'.foreign_key # => "post_id"
199
209
  def foreign_key(separate_class_name_and_id_with_underscore = true)
200
210
  ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
201
211
  end
@@ -2,9 +2,9 @@ require 'active_support/string_inquirer'
2
2
 
3
3
  class String
4
4
  # Wraps the current string in the <tt>ActiveSupport::StringInquirer</tt> class,
5
- # which gives you a prettier way to test for equality. Example:
5
+ # which gives you a prettier way to test for equality.
6
6
  #
7
- # env = "production".inquiry
7
+ # env = 'production'.inquiry
8
8
  # env.production? # => true
9
9
  # env.development? # => false
10
10
  def inquiry
@@ -2,71 +2,48 @@
2
2
  require 'active_support/multibyte'
3
3
 
4
4
  class String
5
- if RUBY_VERSION >= "1.9"
6
- # == Multibyte proxy
7
- #
8
- # +mb_chars+ is a multibyte safe proxy for string methods.
9
- #
10
- # In Ruby 1.8 and older it creates and returns an instance of the ActiveSupport::Multibyte::Chars class which
11
- # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
12
- # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
13
- #
14
- # name = 'Claus Müller'
15
- # name.reverse # => "rell??M sualC"
16
- # name.length # => 13
17
- #
18
- # name.mb_chars.reverse.to_s # => "rellüM sualC"
19
- # name.mb_chars.length # => 12
20
- #
21
- # In Ruby 1.9 and newer +mb_chars+ returns +self+ because String is (mostly) encoding aware. This means that
22
- # it becomes easy to run one version of your code on multiple Ruby versions.
23
- #
24
- # == Method chaining
25
- #
26
- # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
27
- # method chaining on the result of any of these methods.
28
- #
29
- # name.mb_chars.reverse.length # => 12
30
- #
31
- # == Interoperability and configuration
32
- #
33
- # The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between
34
- # String and Char work like expected. The bang! methods change the internal string representation in the Chars
35
- # object. Interoperability problems can be resolved easily with a +to_s+ call.
36
- #
37
- # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
38
- # information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.
39
- def mb_chars
40
- if ActiveSupport::Multibyte.proxy_class.consumes?(self)
41
- ActiveSupport::Multibyte.proxy_class.new(self)
42
- else
43
- self
44
- end
45
- end
46
-
47
- def is_utf8?
48
- case encoding
49
- when Encoding::UTF_8
50
- valid_encoding?
51
- when Encoding::ASCII_8BIT, Encoding::US_ASCII
52
- dup.force_encoding(Encoding::UTF_8).valid_encoding?
53
- else
54
- false
55
- end
56
- end
57
- else
58
- def mb_chars
59
- if ActiveSupport::Multibyte.proxy_class.wants?(self)
60
- ActiveSupport::Multibyte.proxy_class.new(self)
61
- else
62
- self
63
- end
64
- end
5
+ # == Multibyte proxy
6
+ #
7
+ # +mb_chars+ is a multibyte safe proxy for string methods.
8
+ #
9
+ # It creates and returns an instance of the ActiveSupport::Multibyte::Chars class which
10
+ # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
11
+ # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
12
+ #
13
+ # name = 'Claus Müller'
14
+ # name.reverse # => "rell??M sualC"
15
+ # name.length # => 13
16
+ #
17
+ # name.mb_chars.reverse.to_s # => "rellüM sualC"
18
+ # name.mb_chars.length # => 12
19
+ #
20
+ # == Method chaining
21
+ #
22
+ # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
23
+ # method chaining on the result of any of these methods.
24
+ #
25
+ # name.mb_chars.reverse.length # => 12
26
+ #
27
+ # == Interoperability and configuration
28
+ #
29
+ # The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between
30
+ # String and Char work like expected. The bang! methods change the internal string representation in the Chars
31
+ # object. Interoperability problems can be resolved easily with a +to_s+ call.
32
+ #
33
+ # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
34
+ # information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.
35
+ def mb_chars
36
+ ActiveSupport::Multibyte.proxy_class.new(self)
37
+ end
65
38
 
66
- # Returns true if the string has UTF-8 semantics (a String used for purely byte resources is unlikely to have
67
- # them), returns false otherwise.
68
- def is_utf8?
69
- ActiveSupport::Multibyte::Chars.consumes?(self)
39
+ def is_utf8?
40
+ case encoding
41
+ when Encoding::UTF_8
42
+ valid_encoding?
43
+ when Encoding::ASCII_8BIT, Encoding::US_ASCII
44
+ dup.force_encoding(Encoding::UTF_8).valid_encoding?
45
+ else
46
+ false
70
47
  end
71
48
  end
72
49
  end
@@ -3,35 +3,25 @@ require 'active_support/core_ext/kernel/singleton_class'
3
3
 
4
4
  class ERB
5
5
  module Util
6
- HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#x27;' }
6
+ HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#39;' }
7
7
  JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
8
+ HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+));)/
9
+ JSON_ESCAPE_REGEXP = /[&"><]/
8
10
 
9
- if RUBY_VERSION >= '1.9'
10
- # A utility method for escaping HTML tag characters.
11
- # This method is also aliased as <tt>h</tt>.
12
- #
13
- # In your ERB templates, use this method to escape any unsafe content. For example:
14
- # <%=h @person.name %>
15
- #
16
- # ==== Example:
17
- # puts html_escape("is a > 0 & a < 10?")
18
- # # => is a &gt; 0 &amp; a &lt; 10?
19
- def html_escape(s)
20
- s = s.to_s
21
- if s.html_safe?
22
- s
23
- else
24
- s.gsub(/[&"'><]/, HTML_ESCAPE).html_safe
25
- end
26
- end
27
- else
28
- def html_escape(s) #:nodoc:
29
- s = s.to_s
30
- if s.html_safe?
31
- s
32
- else
33
- s.gsub(/[&"'><]/n) { |special| HTML_ESCAPE[special] }.html_safe
34
- end
11
+ # A utility method for escaping HTML tag characters.
12
+ # This method is also aliased as <tt>h</tt>.
13
+ #
14
+ # In your ERB templates, use this method to escape any unsafe content. For example:
15
+ # <%=h @person.name %>
16
+ #
17
+ # puts html_escape('is a > 0 & a < 10?')
18
+ # # => is a &gt; 0 &amp; a &lt; 10?
19
+ def html_escape(s)
20
+ s = s.to_s
21
+ if s.html_safe?
22
+ s
23
+ else
24
+ s.gsub(/[&"'><]/, HTML_ESCAPE).html_safe
35
25
  end
36
26
  end
37
27
 
@@ -44,10 +34,24 @@ class ERB
44
34
  singleton_class.send(:remove_method, :html_escape)
45
35
  module_function :html_escape
46
36
 
37
+ # A utility method for escaping HTML without affecting existing escaped entities.
38
+ #
39
+ # html_escape_once('1 < 2 &amp; 3')
40
+ # # => "1 &lt; 2 &amp; 3"
41
+ #
42
+ # html_escape_once('&lt;&lt; Accept & Checkout')
43
+ # # => "&lt;&lt; Accept &amp; Checkout"
44
+ def html_escape_once(s)
45
+ result = s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
46
+ s.html_safe? ? result.html_safe : result
47
+ end
48
+
49
+ module_function :html_escape_once
50
+
47
51
  # A utility method for escaping HTML entities in JSON strings
48
52
  # using \uXXXX JavaScript escape sequences for string literals:
49
53
  #
50
- # json_escape("is a > 0 & a < 10?")
54
+ # json_escape('is a > 0 & a < 10?')
51
55
  # # => is a \u003E 0 \u0026 a \u003C 10?
52
56
  #
53
57
  # Note that after this operation is performed the output is not
@@ -55,19 +59,11 @@ class ERB
55
59
  #
56
60
  # json_escape('{"name":"john","created_at":"2010-04-28T01:39:31Z","id":1}')
57
61
  # # => {name:john,created_at:2010-04-28T01:39:31Z,id:1}
58
- #
59
- # This method is also aliased as +j+, and available as a helper
60
- # in Rails templates:
61
- #
62
- # <%=j @person.to_json %>
63
- #
64
62
  def json_escape(s)
65
- result = s.to_s.gsub(/[&"><]/) { |special| JSON_ESCAPE[special] }
63
+ result = s.to_s.gsub(JSON_ESCAPE_REGEXP, JSON_ESCAPE)
66
64
  s.html_safe? ? result.html_safe : result
67
65
  end
68
66
 
69
- alias j json_escape
70
- module_function :j
71
67
  module_function :json_escape
72
68
  end
73
69
  end
@@ -86,26 +82,31 @@ end
86
82
 
87
83
  module ActiveSupport #:nodoc:
88
84
  class SafeBuffer < String
89
- UNSAFE_STRING_METHODS = ["capitalize", "chomp", "chop", "delete", "downcase", "gsub", "lstrip", "next", "reverse", "rstrip", "slice", "squeeze", "strip", "sub", "succ", "swapcase", "tr", "tr_s", "upcase", "prepend"].freeze
85
+ UNSAFE_STRING_METHODS = %w(
86
+ capitalize chomp chop delete downcase gsub lstrip next reverse rstrip
87
+ slice squeeze strip sub succ swapcase tr tr_s upcase prepend
88
+ )
90
89
 
91
90
  alias_method :original_concat, :concat
92
91
  private :original_concat
93
92
 
94
93
  class SafeConcatError < StandardError
95
94
  def initialize
96
- super "Could not concatenate to the buffer because it is not html safe."
95
+ super 'Could not concatenate to the buffer because it is not html safe.'
97
96
  end
98
97
  end
99
98
 
100
99
  def [](*args)
101
- return super if args.size < 2
102
-
103
- if html_safe?
104
- new_safe_buffer = super
105
- new_safe_buffer.instance_eval { @html_safe = true }
106
- new_safe_buffer
100
+ if args.size < 2
101
+ super
107
102
  else
108
- to_str[*args]
103
+ if html_safe?
104
+ new_safe_buffer = super
105
+ new_safe_buffer.instance_eval { @html_safe = true }
106
+ new_safe_buffer
107
+ else
108
+ to_str[*args]
109
+ end
109
110
  end
110
111
  end
111
112
 
@@ -141,6 +142,18 @@ module ActiveSupport #:nodoc:
141
142
  dup.concat(other)
142
143
  end
143
144
 
145
+ def %(args)
146
+ args = Array(args).map do |arg|
147
+ if !html_safe? || arg.html_safe?
148
+ arg
149
+ else
150
+ ERB::Util.h(arg)
151
+ end
152
+ end
153
+
154
+ self.class.new(super(args))
155
+ end
156
+
144
157
  def html_safe?
145
158
  defined?(@html_safe) && @html_safe
146
159
  end
@@ -157,11 +170,6 @@ module ActiveSupport #:nodoc:
157
170
  coder.represent_scalar nil, to_str
158
171
  end
159
172
 
160
- def to_yaml(*args)
161
- return super() if defined?(YAML::ENGINE) && !YAML::ENGINE.syck?
162
- to_str.to_yaml(*args)
163
- end
164
-
165
173
  UNSAFE_STRING_METHODS.each do |unsafe_method|
166
174
  if 'String'.respond_to?(unsafe_method)
167
175
  class_eval <<-EOT, __FILE__, __LINE__ + 1
@@ -0,0 +1,13 @@
1
+ require 'active_support/core_ext/time/zones'
2
+
3
+ class String
4
+ # Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default
5
+ # is set, otherwise converts String to a Time via String#to_time
6
+ def in_time_zone(zone = ::Time.zone)
7
+ if zone
8
+ ::Time.find_zone!(zone).parse(self)
9
+ else
10
+ to_time
11
+ end
12
+ end
13
+ end
@@ -4,11 +4,10 @@ require 'active_support/core_ext/string/multibyte'
4
4
  require 'active_support/core_ext/string/starts_ends_with'
5
5
  require 'active_support/core_ext/string/inflections'
6
6
  require 'active_support/core_ext/string/access'
7
- require 'active_support/core_ext/string/xchar'
8
7
  require 'active_support/core_ext/string/behavior'
9
- require 'active_support/core_ext/string/interpolation'
10
8
  require 'active_support/core_ext/string/output_safety'
11
9
  require 'active_support/core_ext/string/exclude'
12
- require 'active_support/core_ext/string/encoding'
13
10
  require 'active_support/core_ext/string/strip'
14
11
  require 'active_support/core_ext/string/inquiry'
12
+ require 'active_support/core_ext/string/indent'
13
+ require 'active_support/core_ext/string/zones'
@@ -0,0 +1,6 @@
1
+ # Backport of Struct#to_h from Ruby 2.0
2
+ class Struct # :nodoc:
3
+ def to_h
4
+ Hash[members.zip(values)]
5
+ end
6
+ end unless Struct.instance_methods.include?(:to_h)
@@ -0,0 +1,74 @@
1
+ class Thread
2
+ LOCK = Mutex.new # :nodoc:
3
+
4
+ # Returns the value of a thread local variable that has been set. Note that
5
+ # these are different than fiber local values.
6
+ #
7
+ # Thread local values are carried along with threads, and do not respect
8
+ # fibers. For example:
9
+ #
10
+ # Thread.new {
11
+ # Thread.current.thread_variable_set("foo", "bar") # set a thread local
12
+ # Thread.current["foo"] = "bar" # set a fiber local
13
+ #
14
+ # Fiber.new {
15
+ # Fiber.yield [
16
+ # Thread.current.thread_variable_get("foo"), # get the thread local
17
+ # Thread.current["foo"], # get the fiber local
18
+ # ]
19
+ # }.resume
20
+ # }.join.value # => ['bar', nil]
21
+ #
22
+ # The value <tt>"bar"</tt> is returned for the thread local, where +nil+ is returned
23
+ # for the fiber local. The fiber is executed in the same thread, so the
24
+ # thread local values are available.
25
+ def thread_variable_get(key)
26
+ locals[key.to_sym]
27
+ end
28
+
29
+ # Sets a thread local with +key+ to +value+. Note that these are local to
30
+ # threads, and not to fibers. Please see Thread#thread_variable_get for
31
+ # more information.
32
+ def thread_variable_set(key, value)
33
+ locals[key.to_sym] = value
34
+ end
35
+
36
+ # Returns an an array of the names of the thread-local variables (as Symbols).
37
+ #
38
+ # thr = Thread.new do
39
+ # Thread.current.thread_variable_set(:cat, 'meow')
40
+ # Thread.current.thread_variable_set("dog", 'woof')
41
+ # end
42
+ # thr.join #=> #<Thread:0x401b3f10 dead>
43
+ # thr.thread_variables #=> [:dog, :cat]
44
+ #
45
+ # Note that these are not fiber local variables. Please see Thread#thread_variable_get
46
+ # for more details.
47
+ def thread_variables
48
+ locals.keys
49
+ end
50
+
51
+ # Returns <tt>true</tt> if the given string (or symbol) exists as a
52
+ # thread-local variable.
53
+ #
54
+ # me = Thread.current
55
+ # me.thread_variable_set(:oliver, "a")
56
+ # me.thread_variable?(:oliver) #=> true
57
+ # me.thread_variable?(:stanley) #=> false
58
+ #
59
+ # Note that these are not fiber local variables. Please see Thread#thread_variable_get
60
+ # for more details.
61
+ def thread_variable?(key)
62
+ locals.has_key?(key.to_sym)
63
+ end
64
+
65
+ private
66
+
67
+ def locals
68
+ if defined?(@locals)
69
+ @locals
70
+ else
71
+ LOCK.synchronize { @locals ||= {} }
72
+ end
73
+ end
74
+ end unless Thread.instance_methods.include?(:thread_variable_set)