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

Improve performance on enforce_available_locales! #249

Merged
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
2 changes: 1 addition & 1 deletion lib/i18n.rb
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ def normalize_keys(locale, key, scope, separator = nil)
# Returns false otherwise.
# Compare with Strings as `locale` may be coming from user input
def locale_available?(locale)
I18n.available_locales.map(&:to_s).include?(locale.to_s)
I18n.config.available_locales_set.include?(locale)
end

# Raises an InvalidLocale exception when the passed locale is not
Expand Down
7 changes: 7 additions & 0 deletions lib/i18n/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,17 @@ def available_locales
@@available_locales || backend.available_locales
end

def available_locales_set
@@available_locales_set ||= available_locales.inject(Set.new) do |set, locale|
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to trade off space for performance in here, So I am adding 2 entries for each locale. (which should be super small anyways). Thus, we dont need to cast to string when looking up.

set << locale.to_s << locale.to_sym
end
end

# Sets the available locales.
def available_locales=(locales)
@@available_locales = Array(locales).map { |locale| locale.to_sym }
@@available_locales = nil if @@available_locales.empty?
@@available_locales_set = nil
end

# Returns the current default scope separator. Defaults to '.'
Expand Down
19 changes: 18 additions & 1 deletion test/i18n_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def setup
assert_equal :de, Thread.current[:i18n_config].locale
I18n.locale = :en
end

test "raises an I18n::InvalidLocale exception when setting an unavailable locale" do
begin
I18n.config.enforce_available_locales = true
Expand Down Expand Up @@ -215,6 +215,23 @@ def setup
end
end

test "available_locales can be replaced at runtime" do
begin
I18n.config.enforce_available_locales = true
assert_raise(I18n::InvalidLocale) { I18n.t(:foo, :locale => 'klingon') }
old_locales, I18n.config.available_locales = I18n.config.available_locales, [:klingon]
I18n.t(:foo, :locale => 'klingon')
ensure
I18n.config.enforce_available_locales = false
I18n.config.available_locales = old_locales
end
end

test "available_locales_set should return a set" do
assert_equal Set, I18n.config.available_locales_set.class
assert_equal (I18n.config.available_locales.size * 2), I18n.config.available_locales_set.size
end

test "exists? given an existing key will return true" do
assert_equal true, I18n.exists?(:currency)
end
Expand Down