PageRenderTime 74ms CodeModel.GetById 5ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/bundle/ruby/1.9.1/gems/activesupport-3.1.0/lib/active_support/inflector/inflections.rb

https://github.com/bublanina/masterlanguage
Ruby | 212 lines | 112 code | 16 blank | 84 comment | 11 complexity | 6e2ba902b1577c5c2b783ad1673177ea MD5 | raw file
  1. # -*- encoding : utf-8 -*-
  2. module ActiveSupport
  3. module Inflector
  4. # A singleton instance of this class is yielded by Inflector.inflections, which can then be used to specify additional
  5. # inflection rules. Examples:
  6. #
  7. # ActiveSupport::Inflector.inflections do |inflect|
  8. # inflect.plural /^(ox)$/i, '\1\2en'
  9. # inflect.singular /^(ox)en/i, '\1'
  10. #
  11. # inflect.irregular 'octopus', 'octopi'
  12. #
  13. # inflect.uncountable "equipment"
  14. # end
  15. #
  16. # New rules are added at the top. So in the example above, the irregular rule for octopus will now be the first of the
  17. # pluralization and singularization rules that is runs. This guarantees that your rules run before any of the rules that may
  18. # already have been loaded.
  19. class Inflections
  20. def self.instance
  21. @__instance__ ||= new
  22. end
  23. attr_reader :plurals, :singulars, :uncountables, :humans
  24. def initialize
  25. @plurals, @singulars, @uncountables, @humans = [], [], [], []
  26. end
  27. # Specifies a new pluralization rule and its replacement. The rule can either be a string or a regular expression.
  28. # The replacement should always be a string that may include references to the matched data from the rule.
  29. def plural(rule, replacement)
  30. @uncountables.delete(rule) if rule.is_a?(String)
  31. @uncountables.delete(replacement)
  32. @plurals.insert(0, [rule, replacement])
  33. end
  34. # Specifies a new singularization rule and its replacement. The rule can either be a string or a regular expression.
  35. # The replacement should always be a string that may include references to the matched data from the rule.
  36. def singular(rule, replacement)
  37. @uncountables.delete(rule) if rule.is_a?(String)
  38. @uncountables.delete(replacement)
  39. @singulars.insert(0, [rule, replacement])
  40. end
  41. # Specifies a new irregular that applies to both pluralization and singularization at the same time. This can only be used
  42. # for strings, not regular expressions. You simply pass the irregular in singular and plural form.
  43. #
  44. # Examples:
  45. # irregular 'octopus', 'octopi'
  46. # irregular 'person', 'people'
  47. def irregular(singular, plural)
  48. @uncountables.delete(singular)
  49. @uncountables.delete(plural)
  50. if singular[0,1].upcase == plural[0,1].upcase
  51. plural(Regexp.new("(#{singular[0,1]})#{singular[1..-1]}$", "i"), '\1' + plural[1..-1])
  52. plural(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + plural[1..-1])
  53. singular(Regexp.new("(#{plural[0,1]})#{plural[1..-1]}$", "i"), '\1' + singular[1..-1])
  54. else
  55. plural(Regexp.new("#{singular[0,1].upcase}(?i)#{singular[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
  56. plural(Regexp.new("#{singular[0,1].downcase}(?i)#{singular[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
  57. plural(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), plural[0,1].upcase + plural[1..-1])
  58. plural(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), plural[0,1].downcase + plural[1..-1])
  59. singular(Regexp.new("#{plural[0,1].upcase}(?i)#{plural[1..-1]}$"), singular[0,1].upcase + singular[1..-1])
  60. singular(Regexp.new("#{plural[0,1].downcase}(?i)#{plural[1..-1]}$"), singular[0,1].downcase + singular[1..-1])
  61. end
  62. end
  63. # Add uncountable words that shouldn't be attempted inflected.
  64. #
  65. # Examples:
  66. # uncountable "money"
  67. # uncountable "money", "information"
  68. # uncountable %w( money information rice )
  69. def uncountable(*words)
  70. (@uncountables << words).flatten!
  71. end
  72. # Specifies a humanized form of a string by a regular expression rule or by a string mapping.
  73. # When using a regular expression based replacement, the normal humanize formatting is called after the replacement.
  74. # When a string is used, the human form should be specified as desired (example: 'The name', not 'the_name')
  75. #
  76. # Examples:
  77. # human /_cnt$/i, '\1_count'
  78. # human "legacy_col_person_name", "Name"
  79. def human(rule, replacement)
  80. @humans.insert(0, [rule, replacement])
  81. end
  82. # Clears the loaded inflections within a given scope (default is <tt>:all</tt>).
  83. # Give the scope as a symbol of the inflection type, the options are: <tt>:plurals</tt>,
  84. # <tt>:singulars</tt>, <tt>:uncountables</tt>, <tt>:humans</tt>.
  85. #
  86. # Examples:
  87. # clear :all
  88. # clear :plurals
  89. def clear(scope = :all)
  90. case scope
  91. when :all
  92. @plurals, @singulars, @uncountables, @humans = [], [], [], []
  93. else
  94. instance_variable_set "@#{scope}", []
  95. end
  96. end
  97. end
  98. # Yields a singleton instance of Inflector::Inflections so you can specify additional
  99. # inflector rules.
  100. #
  101. # Example:
  102. # ActiveSupport::Inflector.inflections do |inflect|
  103. # inflect.uncountable "rails"
  104. # end
  105. def inflections
  106. if block_given?
  107. yield Inflections.instance
  108. else
  109. Inflections.instance
  110. end
  111. end
  112. # Returns the plural form of the word in the string.
  113. #
  114. # Examples:
  115. # "post".pluralize # => "posts"
  116. # "octopus".pluralize # => "octopi"
  117. # "sheep".pluralize # => "sheep"
  118. # "words".pluralize # => "words"
  119. # "CamelOctopus".pluralize # => "CamelOctopi"
  120. def pluralize(word)
  121. result = word.to_s.dup
  122. if word.empty? || inflections.uncountables.include?(result.downcase)
  123. result
  124. else
  125. inflections.plurals.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
  126. result
  127. end
  128. end
  129. # The reverse of +pluralize+, returns the singular form of a word in a string.
  130. #
  131. # Examples:
  132. # "posts".singularize # => "post"
  133. # "octopi".singularize # => "octopus"
  134. # "sheep".singularize # => "sheep"
  135. # "word".singularize # => "word"
  136. # "CamelOctopi".singularize # => "CamelOctopus"
  137. def singularize(word)
  138. result = word.to_s.dup
  139. if inflections.uncountables.any? { |inflection| result =~ /\b(#{inflection})\Z/i }
  140. result
  141. else
  142. inflections.singulars.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
  143. result
  144. end
  145. end
  146. # Capitalizes the first word and turns underscores into spaces and strips a
  147. # trailing "_id", if any. Like +titleize+, this is meant for creating pretty output.
  148. #
  149. # Examples:
  150. # "employee_salary" # => "Employee salary"
  151. # "author_id" # => "Author"
  152. def humanize(lower_case_and_underscored_word)
  153. result = lower_case_and_underscored_word.to_s.dup
  154. inflections.humans.each { |(rule, replacement)| break if result.gsub!(rule, replacement) }
  155. result.gsub(/_id$/, "").gsub(/_/, " ").capitalize
  156. end
  157. # Capitalizes all the words and replaces some characters in the string to create
  158. # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
  159. # used in the Rails internals.
  160. #
  161. # +titleize+ is also aliased as as +titlecase+.
  162. #
  163. # Examples:
  164. # "man from the boondocks".titleize # => "Man From The Boondocks"
  165. # "x-men: the last stand".titleize # => "X Men: The Last Stand"
  166. def titleize(word)
  167. humanize(underscore(word)).gsub(/\b('?[a-z])/) { $1.capitalize }
  168. end
  169. # Create the name of a table like Rails does for models to table names. This method
  170. # uses the +pluralize+ method on the last word in the string.
  171. #
  172. # Examples
  173. # "RawScaledScorer".tableize # => "raw_scaled_scorers"
  174. # "egg_and_ham".tableize # => "egg_and_hams"
  175. # "fancyCategory".tableize # => "fancy_categories"
  176. def tableize(class_name)
  177. pluralize(underscore(class_name))
  178. end
  179. # Create a class name from a plural table name like Rails does for table names to models.
  180. # Note that this returns a string and not a Class. (To convert to an actual class
  181. # follow +classify+ with +constantize+.)
  182. #
  183. # Examples:
  184. # "egg_and_hams".classify # => "EggAndHam"
  185. # "posts".classify # => "Post"
  186. #
  187. # Singular names are not handled correctly:
  188. # "business".classify # => "Busines"
  189. def classify(table_name)
  190. # strip out any leading schema name
  191. camelize(singularize(table_name.to_s.sub(/.*\./, '')))
  192. end
  193. end
  194. end