Skip to content

Commit

Permalink
Fix method redefinition warnings when pluralizations are reloaded
Browse files Browse the repository at this point in the history
Fix: #735

Whenever pluralization rules are reloaded it causes a lot of warnings:

```
lib/rails_i18n/../../rails/pluralization/ar.rb:4: warning: method redefined; discarding old rule
lib/rails_i18n/../../rails/pluralization/ar.rb:4: warning: previous definition of rule was here
lib/rails_i18n/../../rails/pluralization/gd.rb:4: warning: method redefined; discarding old rule
lib/rails_i18n/../../rails/pluralization/gd.rb:4: warning: previous definition of rule was here
lib/rails_i18n/../../rails/pluralization/hsb.rb:4: warning: method redefined; discarding old rule
lib/rails_i18n/../../rails/pluralization/hsb.rb:4: warning: previous definition of rule was here
lib/rails_i18n/../../rails/pluralization/lt.rb:4: warning: method redefined; discarding old rule
lib/rails_i18n/../../rails/pluralization/lt.rb:4: warning: previous definition of rule was here
lib/rails_i18n/../../rails/pluralization/lv.rb:4: warning: method redefined; discarding old rule
lib/rails_i18n/../../rails/pluralization/lv.rb:4: warning: previous definition of rule was here
lib/rails_i18n/../../rails/pluralization/mk.rb:4: warning: method redefined; discarding old rule
lib/rails_i18n/../../rails/pluralization/mk.rb:4: warning: previous definition of rule was here
lib/rails_i18n/../../rails/pluralization/pl.rb:4: warning: method redefined; discarding old rule
lib/rails_i18n/../../rails/pluralization/pl.rb:4: warning: previous definition of rule was here
lib/rails_i18n/../../rails/pluralization/sl.rb:4: warning: method redefined; discarding old rule
lib/rails_i18n/../../rails/pluralization/sl.rb:4: warning: previous definition of rule was here
...
```

This is mostly harmless, but annoying for users who try to run with no warnings at all.
  • Loading branch information
byroot committed Sep 23, 2024
1 parent ea08c7c commit 8b32b36
Show file tree
Hide file tree
Showing 13 changed files with 346 additions and 361 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
- Portuguese (pt): Fixed `number.currency.format.format` and `helpers.submit.update` #1122
- Croatian (hr): use genitive case for month names and put a period after weekday and month abbreviations #1126
- Korean (ko): Add missing keys (Storage units) #1118
- Fix compatibility with frozen string literals. #1120
- Fix compatibility with frozen string literals. #1120
- Refactor translations implemented in Ruby to avoid method redefinition warnings on reload. #1128

## 7.0.9 (2024-03-13)

Expand Down
143 changes: 143 additions & 0 deletions lib/rails_i18n/pluralization.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
module RailsI18n
module Pluralization
module Arabic
def self.rule
lambda do |n|
return :other unless n.is_a?(Numeric)

mod100 = n % 100

if n == 0
:zero
elsif n == 1
:one
elsif n == 2
:two
elsif (3..10).to_a.include?(mod100)
:few
elsif (11..99).to_a.include?(mod100)
:many
else
:other
end
end
end
end

module ScottishGaelic
def self.rule
lambda do |n|
return :other unless n.is_a?(Numeric)

floorn = n.floor

if floorn == 1 || floorn == 11
:one
elsif floorn == 2 || floorn == 12
:two
elsif (3..19).member?(floorn)
:few
else
:other
end
end
end
end

module UpperSorbian
def self.rule
lambda do |n|
return :other unless n.is_a?(Numeric)

mod100 = n % 100

case mod100
when 1 then :one
when 2 then :two
when 3, 4 then :few
else :other
end
end
end
end

module Lithuanian
def self.rule
lambda do |n|
return :other unless n.is_a?(Numeric)

mod10 = n % 10
mod100 = n % 100

if mod10 == 1 && !(11..19).to_a.include?(mod100)
:one
elsif (2..9).to_a.include?(mod10) && !(11..19).to_a.include?(mod100)
:few
else
:other
end
end
end
end

module Latvian
def self.rule
lambda do |n|
if n.is_a?(Numeric) && n % 10 == 1 && n % 100 != 11
:one
else
:other
end
end
end
end

module Macedonian
def self.rule
lambda do |n|
if n.is_a?(Numeric) && n % 10 == 1 && n != 11
:one
else
:other
end
end
end
end

module Polish
def self.rule
lambda do |n|
return :other unless n.is_a?(Numeric)

mod10 = n % 10
mod100 = n % 100

if n == 1
:one
elsif [2, 3, 4].include?(mod10) && ![12, 13, 14].include?(mod100)
:few
elsif [0, 1, 5, 6, 7, 8, 9].include?(mod10) || [12, 13, 14].include?(mod100)
:many
else
:other
end
end
end
end

module Slovenian
def self.rule
lambda do |n|
return :other unless n.is_a?(Numeric)

case n % 100
when 1 then :one
when 2 then :two
when 3, 4 then :few
else :other
end
end
end
end
end
end
191 changes: 191 additions & 0 deletions lib/rails_i18n/transliteration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
# frozen_string_literal: true

module RailsI18n
module Transliteration
module Ukrainian
class << self
def rule
lambda do |string|
next '' unless string

string.gsub(/./) do |char|
# Regexp.last_match is local to the thread and method scope
# of the method that did the pattern match.
@pre_match, @post_match = $`, $'

case char
when 'Ж'
lookahead_upcase 'ZH'
when 'Х'
lookahead_upcase 'KH'
when 'Ц'
lookahead_upcase 'TS'
when 'Ч'
lookahead_upcase 'CH'
when 'Ш'
lookahead_upcase 'SH'
when 'Щ'
lookahead_upcase 'SHCH'
when 'г'
behind =~ /[зЗ]/ ? 'gh' : 'h'
when 'Г'
behind =~ /[зЗ]/ ? lookahead_upcase('GH') : 'H'
when 'є'
letter?(behind) ? 'ie' : 'ye'
when 'Є'
letter?(behind) ? lookahead_upcase('IE') : lookahead_upcase('YE')
when 'ї'
letter?(behind) ? 'i' : 'yi'
when 'Ї'
letter?(behind) ? 'I' : lookahead_upcase('YI')
when 'й'
letter?(behind) ? 'i' : 'y'
when 'Й'
letter?(behind) ? 'I' : 'Y'
when 'ю'
letter?(behind) ? 'iu' : 'yu'
when 'Ю'
letter?(behind) ? lookahead_upcase('IU') : lookahead_upcase('YU')
when 'я'
letter?(behind) ? 'ia' : 'ya'
when 'Я'
letter?(behind) ? lookahead_upcase('IA') : lookahead_upcase('YA')
when "'"
# remove apostrophe inside a word
letter?(behind) && letter?(ahead) ? '' : "'"
else
straight_lookup[char] || char
end
end
end
end

private

def behind
@pre_match && @pre_match[-1]
end

def ahead
@post_match && @post_match[0]
end

def downcased?(symbol)
symbol =~ downcased_regexp
end

def downcased_regexp
@downcased_regexp ||= /[а-яґєії]/
end

# apostrophe can be inside a word
def letter?(symbol)
symbol =~ letter_regexp
end

def letter_regexp
@letter_regexp ||= /[а-яґєіїА-ЯҐЄІЇ'’]/
end

def lookahead_upcase(word)
downcased?(ahead) ? word.capitalize : word.upcase
end

def straight_lookup
@straight_lookup ||= {
'а'=>'a','б'=>'b','в'=>'v','ґ'=>'g','д'=>'d','е'=>'e','ж'=>'zh',
'з'=>'z','и'=>'y','і'=>'i','к'=>'k','л'=>'l','м'=>'m','н'=>'n','о'=>'o',
'п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u','ф'=>'f','х'=>'kh','ц'=>'ts',
'ч'=>'ch','ш'=>'sh','щ'=>'shch','ь'=>'','’'=>'',
'А'=>'A','Б'=>'B','В'=>'V','Ґ'=>'G','Д'=>'D','Е'=>'E',
'З'=>'Z','И'=>'Y','І'=>'I','К'=>'K','Л'=>'L','М'=>'M','Н'=>'N','О'=>'O',
'П'=>'P','Р'=>'R','С'=>'S','Т'=>'T','У'=>'U','Ф'=>'F','Ь'=>''
}
end
end
end

# (c) Yaroslav Markin, Julian "julik" Tarkhanov and Co
# https://github.com/yaroslav/russian/blob/master/lib/russian/transliteration.rb
module Russian
class << self
def rule
lambda do |string|
next '' unless string

chars = string.scan(%r{#{multi_keys.join '|'}|\w|.})

result = +""

chars.each_with_index do |char, index|
if upper.has_key?(char) && lower.has_key?(chars[index+1])
# combined case
result << upper[char].downcase.capitalize
elsif upper.has_key?(char)
result << upper[char]
elsif lower.has_key?(char)
result << lower[char]
else
result << char
end
end

result
end
end

private

# use instance variables instead of constants to prevent warnings
# on re-evaling after I18n.reload!

def upper
@upper ||= begin
upper_single = {
"Ґ"=>"G","Ё"=>"YO","Є"=>"E","Ї"=>"YI","І"=>"I",
"А"=>"A","Б"=>"B","В"=>"V","Г"=>"G",
"Д"=>"D","Е"=>"E","Ж"=>"ZH","З"=>"Z","И"=>"I",
"Й"=>"Y","К"=>"K","Л"=>"L","М"=>"M","Н"=>"N",
"О"=>"O","П"=>"P","Р"=>"R","С"=>"S","Т"=>"T",
"У"=>"U","Ф"=>"F","Х"=>"H","Ц"=>"TS","Ч"=>"CH",
"Ш"=>"SH","Щ"=>"SCH","Ъ"=>"'","Ы"=>"Y","Ь"=>"",
"Э"=>"E","Ю"=>"YU","Я"=>"YA",
}

(upper_single.merge(upper_multi)).freeze
end
end

def lower
@lower ||= begin
lower_single = {
"і"=>"i","ґ"=>"g","ё"=>"yo","№"=>"#","є"=>"e",
"ї"=>"yi","а"=>"a","б"=>"b",
"в"=>"v","г"=>"g","д"=>"d","е"=>"e","ж"=>"zh",
"з"=>"z","и"=>"i","й"=>"y","к"=>"k","л"=>"l",
"м"=>"m","н"=>"n","о"=>"o","п"=>"p","р"=>"r",
"с"=>"s","т"=>"t","у"=>"u","ф"=>"f","х"=>"h",
"ц"=>"ts","ч"=>"ch","ш"=>"sh","щ"=>"sch","ъ"=>"'",
"ы"=>"y","ь"=>"","э"=>"e","ю"=>"yu","я"=>"ya",
}

(lower_single.merge(lower_multi)).freeze
end
end

def upper_multi
@upper_multi ||= { "ЬЕ"=>"IE", "ЬЁ"=>"IE" }
end

def lower_multi
@lower_multi ||= { "ье"=>"ie", "ьё"=>"ie" }
end

def multi_keys
@multi_keys ||= (lower_multi.merge(upper_multi)).keys.sort_by {|s| s.length}.reverse.freeze
end
end
end
end
end

28 changes: 1 addition & 27 deletions rails/pluralization/ar.rb
Original file line number Diff line number Diff line change
@@ -1,30 +1,4 @@
module RailsI18n
module Pluralization
module Arabic
def self.rule
lambda do |n|
return :other unless n.is_a?(Numeric)

mod100 = n % 100

if n == 0
:zero
elsif n == 1
:one
elsif n == 2
:two
elsif (3..10).to_a.include?(mod100)
:few
elsif (11..99).to_a.include?(mod100)
:many
else
:other
end
end
end
end
end
end
require 'rails_i18n/pluralization'

{ :ar => {
:'i18n' => {
Expand Down
Loading

0 comments on commit 8b32b36

Please sign in to comment.