Module: I18n::Backend::Pluralization

Defined in:
lib/i18n/backend/pluralization.rb

Instance Method Summary collapse

Instance Method Details

#pluralize(locale, entry, count) ⇒ Object

Overwrites the Base backend translate method so that it will check the translation meta data space (:i18n) for a locale specific pluralization rule and use it to pluralize the given entry. I.e., the library expects pluralization rules to be stored at I18n.t(:'i18n.plural.rule')

Pluralization rules are expected to respond to #call(count) and return a pluralization key. Valid keys depend on the pluralization rules for the locale, as defined in the CLDR. As of v41, 6 locale-specific plural categories are defined:

:few, :many, :one, :other, :two, :zero

n.b., The :one plural category does not imply the number 1. Instead, :one is a category for any number that behaves like 1 in that locale. For example, in some locales, :one is used for numbers that end in “1” (like 1, 21, 151) but that don't end in 11 (like 11, 111, 10311). Similar notes apply to the :two, and :zero plural categories.

If you want to have different strings for the categories of count == 0 (e.g. “I don't have any cars”) or count == 1 (e.g. “I have a single car”) use the explicit `“0”` and `“1”` keys. unicode-org.github.io/cldr/ldml/tr35-numbers.html#Explicit_0_1_rules


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/i18n/backend/pluralization.rb', line 39

def pluralize(locale, entry, count)
  return entry unless entry.is_a?(Hash) && count

  pluralizer = pluralizer(locale)
  if pluralizer.respond_to?(:call)
    # "0" and "1" are special cases
    # https://unicode-org.github.io/cldr/ldml/tr35-numbers.html#Explicit_0_1_rules
    if count == 0 || count == 1
      value = entry[symbolic_count(count)]
      return value if value
    end

    # Lateral Inheritance of "count" attribute (http://www.unicode.org/reports/tr35/#Lateral_Inheritance):
    # > If there is no value for a path, and that path has a [@count="x"] attribute and value, then:
    # > 1. If "x" is numeric, the path falls back to the path with [@count=«the plural rules category for x for that locale»], within that the same locale.
    # > 2. If "x" is anything but "other", it falls back to a path [@count="other"], within that the same locale.
    # > 3. If "x" is "other", it falls back to the path that is completely missing the count item, within that the same locale.
    # Note: We don't yet implement #3 above, since we haven't decided how lateral inheritance attributes should be represented.
    plural_rule_category = pluralizer.call(count)

    value = if entry.has_key?(plural_rule_category) || entry.has_key?(:other)
      entry[plural_rule_category] || entry[:other]
    else
      raise InvalidPluralizationData.new(entry, count, plural_rule_category)
    end
  else
    super
  end
end