Skip to content

Instantly share code, notes, and snippets.

@yaroslav
Created August 29, 2008 11:14
Show Gist options
  • Save yaroslav/7955 to your computer and use it in GitHub Desktop.
Save yaroslav/7955 to your computer and use it in GitHub Desktop.
i18n SimpleBackend: supporting lambdas for pluralization
# Picks a pluralization rule specified in translation tables for a language or
# uses default pluralization rules.
#
# This is how pluralization rules are defined in translation tables, English
# language for example:
#
# store_translations :'en-US', {
# :pluralize => lambda { |n| n == 1 ? :one : :other }
# }
#
# Rule must return a symbol to use with pluralization, it must be one of:
# :zero, :one, :two, :few, :many, :other
def pluralize(locale, entry, count)
return entry unless entry.is_a?(Hash) and count
key = :zero if count == 0 && entry.has_key?(:zero)
locale_pluralize = lookup(locale, :pluralize)
if locale_pluralize && locale_pluralize.respond_to?(:call)
key ||= locale_pluralize.call(count)
else
key ||= default_pluralizer(count)
end
raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
entry[key]
end
# Default pluralizer, used if pluralization rule is not defined in translations.
#
# Uses English pluralization rules -- it will pick the first translation if count is not equal to 1
# and the second translation if it is equal to 1.
def default_pluralizer(count)
count == 1 ? :one : :other
end
class I18nSimpleBackendPluralizeTest < Test::Unit::TestCase
include I18nSimpleBackendTestSetup
def test_pluralize_calls_lambdas
@backend.store_translations :'ru-RU', {
# one -> n mod 10 is 1 and n mod 100 is not 11;
# few -> n mod 10 in 2..4 and n mod 100 not in 12..14;
# many -> n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14;
# other -> everything else
:pluralize => lambda { |n|
if n.modulo(10) == 1 && n.modulo(100) != 11
:one
elsif (n.modulo(10) >=2 && n.modulo(10) <= 4) && (n.modulo(100) >=12 && n.modulo(100) <= 14)
:few
elsif n.modulo(10) == 0 || (n.modulo(10) >=5 && n.modulo(10) <= 9) ||
(n.modulo(100) >= 11 && n.modulo(100) <= 14)
:many
else
:other
end
}
}
var = {:one => 'вещь', :few => 'вещи', :many => 'вещей', :other => 'вещи'}
assert_equal 'вещь', @backend.send(:pluralize, :'ru-RU', var, 1)
assert_equal 'вещи', @backend.send(:pluralize, :'ru-RU', var, 2)
assert_equal 'вещи', @backend.send(:pluralize, :'ru-RU', var, 3)
assert_equal 'вещей', @backend.send(:pluralize, :'ru-RU', var, 5)
assert_equal 'вещей', @backend.send(:pluralize, :'ru-RU', var, 10)
assert_equal 'вещь', @backend.send(:pluralize, :'ru-RU', var, 21)
assert_equal 'вещей', @backend.send(:pluralize, :'ru-RU', var, 29)
assert_equal 'вещей', @backend.send(:pluralize, :'ru-RU', var, 129)
assert_equal 'вещь', @backend.send(:pluralize, :'ru-RU', var, 131)
end
def test_pluralize_does_not_call_pluralize_if_not_a_proc
@backend.store_translations :'pluralize-not-a-proc', {
:pluralize => "hello",
}
assert_equal 'bar', @backend.send(:pluralize, :'pluralize-not-a-proc', {:one => 'bar', :other => 'bars'}, 1)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment