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
68
69
70
71
72
73
# 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)
    # Deprecation: The use of the `zero` key in this way is incorrect.
    # Users that want a different string for the case of `count == 0` should use the explicit "0" key instead.
    # We keep this incorrect behaviour for now for backwards compatibility until we can remove it.
    # Ref: https://github.com/ruby-i18n/i18n/issues/629
    return entry[:zero] if count == 0 && entry.has_key?(:zero)

    # "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