Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix method redefinition warnings when pluralizations are reloaded #1128

Merged
merged 1 commit into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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