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
@@ -1,25 +1,34 @@
1
+ require 'thread_safe'
2
+ require 'active_support/core_ext/array/prepend_and_append'
3
+ require 'active_support/i18n'
4
+
1
5
  module ActiveSupport
2
6
  module Inflector
3
7
  extend self
4
8
 
5
- # A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
6
- # inflection rules. Examples:
9
+ # A singleton instance of this class is yielded by Inflector.inflections,
10
+ # which can then be used to specify additional inflection rules. If passed
11
+ # an optional locale, rules for other languages can be specified. The
12
+ # default locale is <tt>:en</tt>. Only rules for English are provided.
7
13
  #
8
- # ActiveSupport::Inflector.inflections do |inflect|
14
+ # ActiveSupport::Inflector.inflections(:en) do |inflect|
9
15
  # inflect.plural /^(ox)$/i, '\1\2en'
10
16
  # inflect.singular /^(ox)en/i, '\1'
11
17
  #
12
18
  # inflect.irregular 'octopus', 'octopi'
13
19
  #
14
- # inflect.uncountable "equipment"
20
+ # inflect.uncountable 'equipment'
15
21
  # end
16
22
  #
17
- # New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
18
- # pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
19
- # already have been loaded.
23
+ # New rules are added at the top. So in the example above, the irregular
24
+ # rule for octopus will now be the first of the pluralization and
25
+ # singularization rules that is runs. This guarantees that your rules run
26
+ # before any of the rules that may already have been loaded.
20
27
  class Inflections
21
- def self.instance
22
- @__instance__ ||= new
28
+ @__instance__ = ThreadSafe::Cache.new
29
+
30
+ def self.instance(locale = :en)
31
+ @__instance__[locale] ||= new
23
32
  end
24
33
 
25
34
  attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex
@@ -28,31 +37,41 @@ module ActiveSupport
28
37
  @plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/
29
38
  end
30
39
 
31
- # Specifies a new acronym. An acronym must be specified as it will appear in a camelized string. An underscore
32
- # string that contains the acronym will retain the acronym when passed to `camelize`, `humanize`, or `titleize`.
33
- # A camelized string that contains the acronym will maintain the acronym when titleized or humanized, and will
34
- # convert the acronym into a non-delimited single lowercase word when passed to +underscore+.
40
+ # Private, for the test suite.
41
+ def initialize_dup(orig) # :nodoc:
42
+ %w(plurals singulars uncountables humans acronyms acronym_regex).each do |scope|
43
+ instance_variable_set("@#{scope}", orig.send(scope).dup)
44
+ end
45
+ end
46
+
47
+ # Specifies a new acronym. An acronym must be specified as it will appear
48
+ # in a camelized string. An underscore string that contains the acronym
49
+ # will retain the acronym when passed to +camelize+, +humanize+, or
50
+ # +titleize+. A camelized string that contains the acronym will maintain
51
+ # the acronym when titleized or humanized, and will convert the acronym
52
+ # into a non-delimited single lowercase word when passed to +underscore+.
35
53
  #
36
- # Examples:
37
54
  # acronym 'HTML'
38
- # titleize 'html' #=> 'HTML'
39
- # camelize 'html' #=> 'HTML'
55
+ # titleize 'html' #=> 'HTML'
56
+ # camelize 'html' #=> 'HTML'
40
57
  # underscore 'MyHTML' #=> 'my_html'
41
58
  #
42
- # The acronym, however, must occur as a delimited unit and not be part of another word for conversions to recognize it:
59
+ # The acronym, however, must occur as a delimited unit and not be part of
60
+ # another word for conversions to recognize it:
43
61
  #
44
62
  # acronym 'HTTP'
45
63
  # camelize 'my_http_delimited' #=> 'MyHTTPDelimited'
46
- # camelize 'https' #=> 'Https', not 'HTTPs'
47
- # underscore 'HTTPS' #=> 'http_s', not 'https'
64
+ # camelize 'https' #=> 'Https', not 'HTTPs'
65
+ # underscore 'HTTPS' #=> 'http_s', not 'https'
48
66
  #
49
67
  # acronym 'HTTPS'
50
- # camelize 'https' #=> 'HTTPS'
68
+ # camelize 'https' #=> 'HTTPS'
51
69
  # underscore 'HTTPS' #=> 'https'
52
70
  #
53
- # Note: Acronyms that are passed to `pluralize` will no longer be recognized, since the acronym will not occur as
54
- # a delimited unit in the pluralized result. To work around this, you must specify the pluralized form as an
55
- # acronym as well:
71
+ # Note: Acronyms that are passed to +pluralize+ will no longer be
72
+ # recognized, since the acronym will not occur as a delimited unit in the
73
+ # pluralized result. To work around this, you must specify the pluralized
74
+ # form as an acronym as well:
56
75
  #
57
76
  # acronym 'API'
58
77
  # camelize(pluralize('api')) #=> 'Apis'
@@ -60,90 +79,107 @@ module ActiveSupport
60
79
  # acronym 'APIs'
61
80
  # camelize(pluralize('api')) #=> 'APIs'
62
81
  #
63
- # `acronym` may be used to specify any word that contains an acronym or otherwise needs to maintain a non-standard
64
- # capitalization. The only restriction is that the word must begin with a capital letter.
82
+ # +acronym+ may be used to specify any word that contains an acronym or
83
+ # otherwise needs to maintain a non-standard capitalization. The only
84
+ # restriction is that the word must begin with a capital letter.
65
85
  #
66
- # Examples:
67
86
  # acronym 'RESTful'
68
- # underscore 'RESTful' #=> 'restful'
87
+ # underscore 'RESTful' #=> 'restful'
69
88
  # underscore 'RESTfulController' #=> 'restful_controller'
70
- # titleize 'RESTfulController' #=> 'RESTful Controller'
71
- # camelize 'restful' #=> 'RESTful'
72
- # camelize 'restful_controller' #=> 'RESTfulController'
89
+ # titleize 'RESTfulController' #=> 'RESTful Controller'
90
+ # camelize 'restful' #=> 'RESTful'
91
+ # camelize 'restful_controller' #=> 'RESTfulController'
73
92
  #
74
93
  # acronym 'McDonald'
75
94
  # underscore 'McDonald' #=> 'mcdonald'
76
- # camelize 'mcdonald' #=> 'McDonald'
95
+ # camelize 'mcdonald' #=> 'McDonald'
77
96
  def acronym(word)
78
97
  @acronyms[word.downcase] = word
79
98
  @acronym_regex = /#{@acronyms.values.join("|")}/
80
99
  end
81
100
 
82
- # Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
83
- # The replacement should always be a string that may include references to the matched data from the rule.
101
+ # Specifies a new pluralization rule and its replacement. The rule can
102
+ # either be a string or a regular expression. The replacement should
103
+ # always be a string that may include references to the matched data from
104
+ # the rule.
84
105
  def plural(rule, replacement)
85
106
  @uncountables.delete(rule) if rule.is_a?(String)
86
107
  @uncountables.delete(replacement)
87
- @plurals.insert(0, [rule, replacement])
108
+ @plurals.prepend([rule, replacement])
88
109
  end
89
110
 
90
- # Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
91
- # The replacement should always be a string that may include references to the matched data from the rule.
111
+ # Specifies a new singularization rule and its replacement. The rule can
112
+ # either be a string or a regular expression. The replacement should
113
+ # always be a string that may include references to the matched data from
114
+ # the rule.
92
115
  def singular(rule, replacement)
93
116
  @uncountables.delete(rule) if rule.is_a?(String)
94
117
  @uncountables.delete(replacement)
95
- @singulars.insert(0, [rule, replacement])
118
+ @singulars.prepend([rule, replacement])
96
119
  end
97
120
 
98
- # Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
99
- # for strings, not regular expressions. You simply pass the irregular in singular and plural form.
121
+ # Specifies a new irregular that applies to both pluralization and
122
+ # singularization at the same time. This can only be used for strings, not
123
+ # regular expressions. You simply pass the irregular in singular and
124
+ # plural form.
100
125
  #
101
- # Examples:
102
126
  # irregular 'octopus', 'octopi'
103
127
  # irregular 'person', 'people'
104
128
  def irregular(singular, plural)
105
129
  @uncountables.delete(singular)
106
130
  @uncountables.delete(plural)
107
- if singular[0,1].upcase == plural[0,1].upcase
108
- plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
109
- plural(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + plural[1..-1])
110
- singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
131
+
132
+ s0 = singular[0]
133
+ srest = singular[1..-1]
134
+
135
+ p0 = plural[0]
136
+ prest = plural[1..-1]
137
+
138
+ if s0.upcase == p0.upcase
139
+ plural(/(#{s0})#{srest}$/i, '\1' + prest)
140
+ plural(/(#{p0})#{prest}$/i, '\1' + prest)
141
+
142
+ singular(/(#{s0})#{srest}$/i, '\1' + srest)
143
+ singular(/(#{p0})#{prest}$/i, '\1' + srest)
111
144
  else
112
- plural(Regexp.new("#{singular[0,1].upcase}(?i)#{singular[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
113
- plural(Regexp.new("#{singular[0,1].downcase}(?i)#{singular[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
114
- plural(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
115
- plural(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
116
- singular(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), singular[0,1].upcase + singular[1..-1])
117
- singular(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), singular[0,1].downcase + singular[1..-1])
145
+ plural(/#{s0.upcase}(?i)#{srest}$/, p0.upcase + prest)
146
+ plural(/#{s0.downcase}(?i)#{srest}$/, p0.downcase + prest)
147
+ plural(/#{p0.upcase}(?i)#{prest}$/, p0.upcase + prest)
148
+ plural(/#{p0.downcase}(?i)#{prest}$/, p0.downcase + prest)
149
+
150
+ singular(/#{s0.upcase}(?i)#{srest}$/, s0.upcase + srest)
151
+ singular(/#{s0.downcase}(?i)#{srest}$/, s0.downcase + srest)
152
+ singular(/#{p0.upcase}(?i)#{prest}$/, s0.upcase + srest)
153
+ singular(/#{p0.downcase}(?i)#{prest}$/, s0.downcase + srest)
118
154
  end
119
155
  end
120
156
 
121
157
  # Add uncountable words that shouldn't be attempted inflected.
122
158
  #
123
- # Examples:
124
- # uncountable "money"
125
- # uncountable "money", "information"
159
+ # uncountable 'money'
160
+ # uncountable 'money', 'information'
126
161
  # uncountable %w( money information rice )
127
162
  def uncountable(*words)
128
163
  (@uncountables << words).flatten!
129
164
  end
130
165
 
131
- # Specifies a humanized form of a string by a regular expression rule or by a string mapping.
132
- # When using a regular expression based replacement, the normal humanize formatting is called after the replacement.
133
- # When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name')
166
+ # Specifies a humanized form of a string by a regular expression rule or
167
+ # by a string mapping. When using a regular expression based replacement,
168
+ # the normal humanize formatting is called after the replacement. When a
169
+ # string is used, the human form should be specified as desired (example:
170
+ # 'The name', not 'the_name').
134
171
  #
135
- # Examples:
136
172
  # human /_cnt$/i, '\1_count'
137
- # human "legacy_col_person_name", "Name"
173
+ # human 'legacy_col_person_name', 'Name'
138
174
  def human(rule, replacement)
139
- @humans.insert(0, [rule, replacement])
175
+ @humans.prepend([rule, replacement])
140
176
  end
141
177
 
142
- # Clears the loaded inflections within a given scope (default is <tt>:all</tt>).
143
- # Give the scope as a symbol of the inflection type, the options are: <tt>:plurals</tt>,
144
- # <tt>:singulars</tt>, <tt>:uncountables</tt>, <tt>:humans</tt>.
178
+ # Clears the loaded inflections within a given scope (default is
179
+ # <tt>:all</tt>). Give the scope as a symbol of the inflection type, the
180
+ # options are: <tt>:plurals</tt>, <tt>:singulars</tt>, <tt>:uncountables</tt>,
181
+ # <tt>:humans</tt>.
145
182
  #
146
- # Examples:
147
183
  # clear :all
148
184
  # clear :plurals
149
185
  def clear(scope = :all)
@@ -156,18 +192,19 @@ module ActiveSupport
156
192
  end
157
193
  end
158
194
 
159
- # Yields a singleton instance of Inflector::Inflections so you can specify additional
160
- # inflector rules.
195
+ # Yields a singleton instance of Inflector::Inflections so you can specify
196
+ # additional inflector rules. If passed an optional locale, rules for other
197
+ # languages can be specified. If not specified, defaults to <tt>:en</tt>.
198
+ # Only rules for English are provided.
161
199
  #
162
- # Example:
163
- # ActiveSupport::Inflector.inflections do |inflect|
164
- # inflect.uncountable "rails"
200
+ # ActiveSupport::Inflector.inflections(:en) do |inflect|
201
+ # inflect.uncountable 'rails'
165
202
  # end
166
- def inflections
203
+ def inflections(locale = :en)
167
204
  if block_given?
168
- yield Inflections.instance
205
+ yield Inflections.instance(locale)
169
206
  else
170
- Inflections.instance
207
+ Inflections.instance(locale)
171
208
  end
172
209
  end
173
210
  end