activesupport 3.2.22.5 → 4.0.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 (214) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +325 -136
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +4 -2
  5. data/lib/active_support.rb +8 -21
  6. data/lib/active_support/backtrace_cleaner.rb +33 -25
  7. data/lib/active_support/basic_object.rb +7 -17
  8. data/lib/active_support/benchmarkable.rb +19 -15
  9. data/lib/active_support/buffered_logger.rb +9 -113
  10. data/lib/active_support/cache.rb +203 -171
  11. data/lib/active_support/cache/file_store.rb +12 -12
  12. data/lib/active_support/cache/mem_cache_store.rb +24 -30
  13. data/lib/active_support/cache/memory_store.rb +2 -0
  14. data/lib/active_support/callbacks.rb +195 -247
  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.rb +1 -0
  19. data/lib/active_support/core_ext/array.rb +0 -1
  20. data/lib/active_support/core_ext/array/access.rb +17 -9
  21. data/lib/active_support/core_ext/array/conversions.rb +113 -55
  22. data/lib/active_support/core_ext/array/extract_options.rb +2 -2
  23. data/lib/active_support/core_ext/array/grouping.rb +21 -22
  24. data/lib/active_support/core_ext/array/uniq_by.rb +12 -9
  25. data/lib/active_support/core_ext/array/wrap.rb +11 -14
  26. data/lib/active_support/core_ext/big_decimal/conversions.rb +7 -24
  27. data/lib/active_support/core_ext/class/attribute.rb +12 -8
  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.rb +6 -0
  32. data/lib/active_support/core_ext/date/calculations.rb +34 -188
  33. data/lib/active_support/core_ext/date/conversions.rb +16 -38
  34. data/lib/active_support/core_ext/date/infinite_comparable.rb +5 -0
  35. data/lib/active_support/core_ext/date/zones.rb +25 -2
  36. data/lib/active_support/core_ext/date_and_time/calculations.rb +232 -0
  37. data/lib/active_support/core_ext/date_time.rb +5 -0
  38. data/lib/active_support/core_ext/date_time/acts_like.rb +0 -1
  39. data/lib/active_support/core_ext/date_time/calculations.rb +73 -65
  40. data/lib/active_support/core_ext/date_time/conversions.rb +21 -33
  41. data/lib/active_support/core_ext/date_time/infinite_comparable.rb +5 -0
  42. data/lib/active_support/core_ext/date_time/zones.rb +11 -8
  43. data/lib/active_support/core_ext/enumerable.rb +26 -73
  44. data/lib/active_support/core_ext/file.rb +0 -1
  45. data/lib/active_support/core_ext/file/atomic.rb +27 -11
  46. data/lib/active_support/core_ext/hash.rb +0 -1
  47. data/lib/active_support/core_ext/hash/conversions.rb +145 -79
  48. data/lib/active_support/core_ext/hash/deep_merge.rb +14 -8
  49. data/lib/active_support/core_ext/hash/diff.rb +5 -4
  50. data/lib/active_support/core_ext/hash/except.rb +1 -9
  51. data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -5
  52. data/lib/active_support/core_ext/hash/keys.rb +108 -24
  53. data/lib/active_support/core_ext/hash/reverse_merge.rb +2 -3
  54. data/lib/active_support/core_ext/hash/slice.rb +12 -12
  55. data/lib/active_support/core_ext/infinite_comparable.rb +35 -0
  56. data/lib/active_support/core_ext/integer/inflections.rb +13 -1
  57. data/lib/active_support/core_ext/integer/time.rb +17 -12
  58. data/lib/active_support/core_ext/kernel/debugger.rb +2 -2
  59. data/lib/active_support/core_ext/kernel/reporting.rb +36 -22
  60. data/lib/active_support/core_ext/kernel/singleton_class.rb +0 -7
  61. data/lib/active_support/core_ext/load_error.rb +7 -5
  62. data/lib/active_support/core_ext/logger.rb +7 -23
  63. data/lib/active_support/core_ext/marshal.rb +19 -0
  64. data/lib/active_support/core_ext/module.rb +1 -3
  65. data/lib/active_support/core_ext/module/aliasing.rb +8 -9
  66. data/lib/active_support/core_ext/module/anonymous.rb +2 -7
  67. data/lib/active_support/core_ext/module/attr_internal.rb +0 -1
  68. data/lib/active_support/core_ext/module/attribute_accessors.rb +12 -10
  69. data/lib/active_support/core_ext/module/delegation.rb +57 -40
  70. data/lib/active_support/core_ext/module/deprecation.rb +19 -3
  71. data/lib/active_support/core_ext/module/introspection.rb +17 -27
  72. data/lib/active_support/core_ext/module/qualified_const.rb +8 -20
  73. data/lib/active_support/core_ext/module/remove_method.rb +1 -5
  74. data/lib/active_support/core_ext/numeric.rb +2 -0
  75. data/lib/active_support/core_ext/numeric/conversions.rb +135 -0
  76. data/lib/active_support/core_ext/numeric/infinite_comparable.rb +9 -0
  77. data/lib/active_support/core_ext/numeric/time.rb +6 -6
  78. data/lib/active_support/core_ext/object.rb +1 -0
  79. data/lib/active_support/core_ext/object/acts_like.rb +4 -4
  80. data/lib/active_support/core_ext/object/blank.rb +7 -23
  81. data/lib/active_support/core_ext/object/deep_dup.rb +46 -0
  82. data/lib/active_support/core_ext/object/duplicable.rb +1 -30
  83. data/lib/active_support/core_ext/object/inclusion.rb +6 -6
  84. data/lib/active_support/core_ext/object/instance_variables.rb +7 -12
  85. data/lib/active_support/core_ext/object/to_json.rb +8 -0
  86. data/lib/active_support/core_ext/object/to_param.rb +5 -2
  87. data/lib/active_support/core_ext/object/try.rb +46 -25
  88. data/lib/active_support/core_ext/object/with_options.rb +7 -8
  89. data/lib/active_support/core_ext/proc.rb +3 -0
  90. data/lib/active_support/core_ext/range.rb +0 -2
  91. data/lib/active_support/core_ext/range/conversions.rb +0 -2
  92. data/lib/active_support/core_ext/range/include_range.rb +1 -1
  93. data/lib/active_support/core_ext/range/overlaps.rb +1 -1
  94. data/lib/active_support/core_ext/string.rb +2 -2
  95. data/lib/active_support/core_ext/string/access.rb +95 -90
  96. data/lib/active_support/core_ext/string/conversions.rb +29 -38
  97. data/lib/active_support/core_ext/string/encoding.rb +6 -9
  98. data/lib/active_support/core_ext/string/filters.rb +24 -18
  99. data/lib/active_support/core_ext/string/indent.rb +43 -0
  100. data/lib/active_support/core_ext/string/inflections.rb +70 -60
  101. data/lib/active_support/core_ext/string/inquiry.rb +2 -2
  102. data/lib/active_support/core_ext/string/multibyte.rb +41 -64
  103. data/lib/active_support/core_ext/string/output_safety.rb +59 -51
  104. data/lib/active_support/core_ext/string/zones.rb +13 -0
  105. data/lib/active_support/core_ext/struct.rb +6 -0
  106. data/lib/active_support/core_ext/thread.rb +74 -0
  107. data/lib/active_support/core_ext/time.rb +6 -0
  108. data/lib/active_support/core_ext/time/calculations.rb +105 -193
  109. data/lib/active_support/core_ext/time/conversions.rb +27 -51
  110. data/lib/active_support/core_ext/time/infinite_comparable.rb +5 -0
  111. data/lib/active_support/core_ext/time/marshal.rb +0 -27
  112. data/lib/active_support/core_ext/time/zones.rb +27 -17
  113. data/lib/active_support/core_ext/uri.rb +13 -17
  114. data/lib/active_support/dependencies.rb +160 -141
  115. data/lib/active_support/dependencies/autoload.rb +47 -20
  116. data/lib/active_support/deprecation.rb +39 -14
  117. data/lib/active_support/deprecation/behaviors.rb +44 -30
  118. data/lib/active_support/deprecation/instance_delegator.rb +24 -0
  119. data/lib/active_support/deprecation/method_wrappers.rb +33 -18
  120. data/lib/active_support/deprecation/proxy_wrappers.rb +58 -13
  121. data/lib/active_support/deprecation/reporting.rb +40 -11
  122. data/lib/active_support/descendants_tracker.rb +34 -19
  123. data/lib/active_support/duration.rb +6 -8
  124. data/lib/active_support/file_update_checker.rb +63 -47
  125. data/lib/active_support/gzip.rb +11 -5
  126. data/lib/active_support/hash_with_indifferent_access.rb +112 -37
  127. data/lib/active_support/i18n.rb +4 -0
  128. data/lib/active_support/i18n_railtie.rb +5 -22
  129. data/lib/active_support/inflections.rb +14 -12
  130. data/lib/active_support/inflector/inflections.rb +108 -71
  131. data/lib/active_support/inflector/methods.rb +181 -160
  132. data/lib/active_support/inflector/transliterate.rb +16 -17
  133. data/lib/active_support/json/decoding.rb +18 -17
  134. data/lib/active_support/json/encoding.rb +93 -39
  135. data/lib/active_support/json/variable.rb +10 -1
  136. data/lib/active_support/key_generator.rb +75 -0
  137. data/lib/active_support/lazy_load_hooks.rb +21 -19
  138. data/lib/active_support/locale/en.yml +100 -3
  139. data/lib/active_support/log_subscriber.rb +56 -36
  140. data/lib/active_support/log_subscriber/test_helper.rb +18 -15
  141. data/lib/active_support/logger.rb +57 -0
  142. data/lib/active_support/logger_silence.rb +24 -0
  143. data/lib/active_support/message_encryptor.rb +32 -29
  144. data/lib/active_support/message_verifier.rb +8 -14
  145. data/lib/active_support/multibyte.rb +5 -28
  146. data/lib/active_support/multibyte/chars.rb +80 -333
  147. data/lib/active_support/multibyte/unicode.rb +74 -64
  148. data/lib/active_support/notifications.rb +57 -25
  149. data/lib/active_support/notifications/fanout.rb +105 -18
  150. data/lib/active_support/notifications/instrumenter.rb +32 -13
  151. data/lib/active_support/number_helper.rb +636 -0
  152. data/lib/active_support/ordered_hash.rb +8 -190
  153. data/lib/active_support/ordered_options.rb +21 -23
  154. data/lib/active_support/proxy_object.rb +13 -0
  155. data/lib/active_support/rails.rb +27 -0
  156. data/lib/active_support/railtie.rb +12 -32
  157. data/lib/active_support/rescuable.rb +9 -4
  158. data/lib/active_support/string_inquirer.rb +13 -8
  159. data/lib/active_support/tagged_logging.rb +51 -73
  160. data/lib/active_support/test_case.rb +46 -17
  161. data/lib/active_support/testing/assertions.rb +56 -26
  162. data/lib/active_support/testing/autorun.rb +5 -0
  163. data/lib/active_support/testing/constant_lookup.rb +52 -0
  164. data/lib/active_support/testing/declarative.rb +1 -1
  165. data/lib/active_support/testing/deprecation.rb +0 -19
  166. data/lib/active_support/testing/isolation.rb +25 -58
  167. data/lib/active_support/testing/pending.rb +5 -43
  168. data/lib/active_support/testing/setup_and_teardown.rb +6 -92
  169. data/lib/active_support/testing/tagged_logging.rb +25 -0
  170. data/lib/active_support/time.rb +6 -21
  171. data/lib/active_support/time_with_zone.rb +78 -43
  172. data/lib/active_support/values/time_zone.rb +77 -58
  173. data/lib/active_support/values/unicode_tables.dat +0 -0
  174. data/lib/active_support/version.rb +4 -4
  175. data/lib/active_support/xml_mini.rb +35 -17
  176. data/lib/active_support/xml_mini/jdom.rb +9 -17
  177. data/lib/active_support/xml_mini/libxml.rb +1 -2
  178. data/lib/active_support/xml_mini/libxmlsax.rb +1 -2
  179. data/lib/active_support/xml_mini/nokogiri.rb +1 -2
  180. data/lib/active_support/xml_mini/nokogirisax.rb +1 -2
  181. data/lib/active_support/xml_mini/rexml.rb +6 -8
  182. metadata +107 -77
  183. data/lib/active_support/base64.rb +0 -54
  184. data/lib/active_support/core_ext/array/random_access.rb +0 -30
  185. data/lib/active_support/core_ext/date/freeze.rb +0 -33
  186. data/lib/active_support/core_ext/exception.rb +0 -3
  187. data/lib/active_support/core_ext/file/path.rb +0 -5
  188. data/lib/active_support/core_ext/float.rb +0 -1
  189. data/lib/active_support/core_ext/float/rounding.rb +0 -19
  190. data/lib/active_support/core_ext/hash/deep_dup.rb +0 -18
  191. data/lib/active_support/core_ext/io.rb +0 -15
  192. data/lib/active_support/core_ext/module/method_names.rb +0 -14
  193. data/lib/active_support/core_ext/module/synchronization.rb +0 -45
  194. data/lib/active_support/core_ext/process.rb +0 -1
  195. data/lib/active_support/core_ext/process/daemon.rb +0 -23
  196. data/lib/active_support/core_ext/range/blockless_step.rb +0 -29
  197. data/lib/active_support/core_ext/range/cover.rb +0 -3
  198. data/lib/active_support/core_ext/rexml.rb +0 -46
  199. data/lib/active_support/core_ext/string/interpolation.rb +0 -2
  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.rb +0 -317
  208. data/lib/active_support/testing/performance/jruby.rb +0 -115
  209. data/lib/active_support/testing/performance/rubinius.rb +0 -113
  210. data/lib/active_support/testing/performance/ruby.rb +0 -152
  211. data/lib/active_support/testing/performance/ruby/mri.rb +0 -57
  212. data/lib/active_support/testing/performance/ruby/yarv.rb +0 -57
  213. data/lib/active_support/time/autoload.rb +0 -5
  214. data/lib/active_support/whiny_nil.rb +0 -24
@@ -1,43 +1,38 @@
1
- # encoding: utf-8
2
1
  require 'date'
3
- require 'active_support/core_ext/time/publicize_conversion_methods'
4
2
  require 'active_support/core_ext/time/calculations'
5
3
 
6
4
  class String
7
- # Returns the codepoint of the first character of the string, assuming a
8
- # single-byte character encoding:
5
+ # Converts a string to a Time value.
6
+ # The +form+ can be either :utc or :local (default :local).
9
7
  #
10
- # "a".ord # => 97
11
- # "à".ord # => 224, in ISO-8859-1
8
+ # The time is parsed using Time.parse method.
9
+ # If +form+ is :local, then the time is in the system timezone.
10
+ # If the date part is missing then the current date is used and if
11
+ # the time part is missing then it is assumed to be 00:00:00.
12
12
  #
13
- # This method is defined in Ruby 1.8 for Ruby 1.9 forward compatibility on
14
- # these character encodings.
15
- #
16
- # <tt>ActiveSupport::Multibyte::Chars#ord</tt> is forward compatible with
17
- # Ruby 1.9 on UTF8 strings:
18
- #
19
- # "a".mb_chars.ord # => 97
20
- # "à".mb_chars.ord # => 224, in UTF8
21
- #
22
- # Note that the 224 is different in both examples. In ISO-8859-1 "à" is
23
- # represented as a single byte, 224. In UTF8 it is represented with two
24
- # bytes, namely 195 and 160, but its Unicode codepoint is 224. If we
25
- # call +ord+ on the UTF8 string "à" the return value will be 195. That is
26
- # not an error, because UTF8 is unsupported, the call itself would be
27
- # bogus.
28
- def ord
29
- self[0]
30
- end unless method_defined?(:ord)
13
+ # "13-12-2012".to_time # => 2012-12-13 00:00:00 +0100
14
+ # "06:12".to_time # => 2012-12-13 06:12:00 +0100
15
+ # "2012-12-13 06:12".to_time # => 2012-12-13 06:12:00 +0100
16
+ # "2012-12-13T06:12".to_time # => 2012-12-13 06:12:00 +0100
17
+ # "2012-12-13T06:12".to_time(:utc) # => 2012-12-13 05:12:00 UTC
18
+ def to_time(form = :local)
19
+ parts = Date._parse(self, false)
20
+ return if parts.empty?
31
21
 
32
- # +getbyte+ backport from Ruby 1.9
33
- alias_method :getbyte, :[] unless method_defined?(:getbyte)
22
+ now = Time.now
23
+ offset = parts[:offset]
24
+ utc_offset = form == :utc ? 0 : now.utc_offset
25
+ adjustment = offset ? offset - utc_offset : 0
34
26
 
35
- # Form can be either :utc (default) or :local.
36
- def to_time(form = :utc)
37
- return nil if self.blank?
38
- d = ::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset).map { |arg| arg || 0 }
39
- d[6] *= 1000000
40
- ::Time.send("#{form}_time", *d[0..6]) - d[7]
27
+ Time.send(
28
+ form,
29
+ parts.fetch(:year, now.year),
30
+ parts.fetch(:mon, now.month),
31
+ parts.fetch(:mday, now.day),
32
+ parts.fetch(:hour, 0),
33
+ parts.fetch(:min, 0),
34
+ parts.fetch(:sec, 0) + parts.fetch(:sec_fraction, 0)
35
+ ) - adjustment
41
36
  end
42
37
 
43
38
  # Converts a string to a Date value.
@@ -47,8 +42,7 @@ class String
47
42
  # "2012-12-13".to_date #=> Thu, 13 Dec 2012
48
43
  # "12/13/2012".to_date #=> ArgumentError: invalid date
49
44
  def to_date
50
- return nil if self.blank?
51
- ::Date.new(*::Date._parse(self, false).values_at(:year, :mon, :mday))
45
+ ::Date.parse(self, false) unless blank?
52
46
  end
53
47
 
54
48
  # Converts a string to a DateTime value.
@@ -58,9 +52,6 @@ class String
58
52
  # "2012-12-13 12:50".to_datetime #=> Thu, 13 Dec 2012 12:50:00 +0000
59
53
  # "12/13/2012".to_datetime #=> ArgumentError: invalid date
60
54
  def to_datetime
61
- return nil if self.blank?
62
- d = ::Date._parse(self, false).values_at(:year, :mon, :mday, :hour, :min, :sec, :zone, :sec_fraction).map { |arg| arg || 0 }
63
- d[5] += d.pop
64
- ::DateTime.civil(*d)
55
+ ::DateTime.parse(self, false) unless blank?
65
56
  end
66
57
  end
@@ -1,11 +1,8 @@
1
+ require 'active_support/deprecation'
2
+
1
3
  class String
2
- if defined?(Encoding) && "".respond_to?(:encode)
3
- def encoding_aware?
4
- true
5
- end
6
- else
7
- def encoding_aware?
8
- false
9
- end
4
+ def encoding_aware?
5
+ ActiveSupport::Deprecation.warn 'String#encoding_aware? is deprecated'
6
+ true
10
7
  end
11
- end
8
+ end
@@ -1,11 +1,10 @@
1
- require 'active_support/core_ext/string/multibyte'
2
-
3
1
  class String
4
2
  # Returns the string, first removing all whitespace on both ends of
5
3
  # the string, and then changing remaining consecutive whitespace
6
4
  # groups into one space each.
7
5
  #
8
- # Examples:
6
+ # Note that it handles both ASCII and Unicode whitespace like mongolian vowel separator (U+180E).
7
+ #
9
8
  # %{ Multi-line
10
9
  # string }.squish # => "Multi-line string"
11
10
  # " foo bar \n \t boo".squish # => "foo bar boo"
@@ -15,35 +14,42 @@ class String
15
14
 
16
15
  # Performs a destructive squish. See String#squish.
17
16
  def squish!
18
- strip!
19
- gsub!(/\s+/, ' ')
17
+ gsub!(/\A[[:space:]]+/, '')
18
+ gsub!(/[[:space:]]+\z/, '')
19
+ gsub!(/[[:space:]]+/, ' ')
20
20
  self
21
21
  end
22
22
 
23
23
  # Truncates a given +text+ after a given <tt>length</tt> if +text+ is longer than <tt>length</tt>:
24
24
  #
25
- # "Once upon a time in a world far far away".truncate(27)
25
+ # 'Once upon a time in a world far far away'.truncate(27)
26
26
  # # => "Once upon a time in a wo..."
27
27
  #
28
- # Pass a <tt>:separator</tt> to truncate +text+ at a natural break:
28
+ # Pass a string or regexp <tt>:separator</tt> to truncate +text+ at a natural break:
29
+ #
30
+ # 'Once upon a time in a world far far away'.truncate(27, separator: ' ')
31
+ # # => "Once upon a time in a..."
29
32
  #
30
- # "Once upon a time in a world far far away".truncate(27, :separator => ' ')
33
+ # 'Once upon a time in a world far far away'.truncate(27, separator: /\s/)
31
34
  # # => "Once upon a time in a..."
32
35
  #
33
36
  # The last characters will be replaced with the <tt>:omission</tt> string (defaults to "...")
34
- # for a total length not exceeding <tt>:length</tt>:
37
+ # for a total length not exceeding <tt>length</tt>:
35
38
  #
36
- # "And they found that many people were sleeping better.".truncate(25, :omission => "... (continued)")
39
+ # 'And they found that many people were sleeping better.'.truncate(25, omission: '... (continued)')
37
40
  # # => "And they f... (continued)"
38
- def truncate(length, options = {})
39
- text = self.dup
40
- options[:omission] ||= "..."
41
+ def truncate(truncate_at, options = {})
42
+ return dup unless length > truncate_at
41
43
 
42
- length_with_room_for_omission = length - options[:omission].mb_chars.length
43
- chars = text.mb_chars
44
- stop = options[:separator] ?
45
- (chars.rindex(options[:separator].mb_chars, length_with_room_for_omission) || length_with_room_for_omission) : length_with_room_for_omission
44
+ options[:omission] ||= '...'
45
+ length_with_room_for_omission = truncate_at - options[:omission].length
46
+ stop = \
47
+ if options[:separator]
48
+ rindex(options[:separator], length_with_room_for_omission) || length_with_room_for_omission
49
+ else
50
+ length_with_room_for_omission
51
+ end
46
52
 
47
- (chars.length > length ? chars[0...stop] + options[:omission] : text).to_s
53
+ self[0...stop] + options[:omission]
48
54
  end
49
55
  end
@@ -0,0 +1,43 @@
1
+ class String
2
+ # Same as +indent+, except it indents the receiver in-place.
3
+ #
4
+ # Returns the indented string, or +nil+ if there was nothing to indent.
5
+ def indent!(amount, indent_string=nil, indent_empty_lines=false)
6
+ indent_string = indent_string || self[/^[ \t]/] || ' '
7
+ re = indent_empty_lines ? /^/ : /^(?!$)/
8
+ gsub!(re, indent_string * amount)
9
+ end
10
+
11
+ # Indents the lines in the receiver:
12
+ #
13
+ # <<EOS.indent(2)
14
+ # def some_method
15
+ # some_code
16
+ # end
17
+ # EOS
18
+ # # =>
19
+ # def some_method
20
+ # some_code
21
+ # end
22
+ #
23
+ # The second argument, +indent_string+, specifies which indent string to
24
+ # use. The default is +nil+, which tells the method to make a guess by
25
+ # peeking at the first indented line, and fallback to a space if there is
26
+ # none.
27
+ #
28
+ # " foo".indent(2) # => " foo"
29
+ # "foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar"
30
+ # "foo".indent(2, "\t") # => "\t\tfoo"
31
+ #
32
+ # While +indent_string+ is tipically one space or tab, it may be any string.
33
+ #
34
+ # The third argument, +indent_empty_lines+, is a flag that says whether
35
+ # empty lines should be indented. Default is false.
36
+ #
37
+ # "foo\n\nbar".indent(2) # => " foo\n\n bar"
38
+ # "foo\n\nbar".indent(2, nil, true) # => " foo\n \n bar"
39
+ #
40
+ def indent(amount, indent_string=nil, indent_empty_lines=false)
41
+ dup.tap {|_| _.indent!(amount, indent_string, indent_empty_lines)}
42
+ end
43
+ end
@@ -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 paramter 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