公司某个项目要做多语言支持了,由于我不确定 I18n.locale
是不是全局变量,所以查了下源代码,发现 I18n.locale
是保存在 thread-local variable 中的:
# Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
def locale=(locale)
I18n.enforce_available_locales!(locale)
@locale = locale && locale.to_sym
end
Reference:https://github.com/svenfuchs/i18n/blob/v0.7.0/lib/i18n/config.rb#L11
大概是为了在多线程环境(比如 puma)中避免请求之间相互影响。
多线程环境下,多个请求是可以并行被不同线程处理的,若使用全局变量,一个请求中修改了 I18n.locale
,其它线程正在处理的请求也会受影响。
1. 若在一个请求中修改了 I18n.locale
,其它线程的后续请求不会受影响,当前线程的后续请求可能会受影响:
I18n.locale
,则不受影响I18n.locale
,那么 I18n.locale
的值不是配置文件中配置的默认值,而是之前的请求设置的值然而请求一般是被随机的分配给各个线程处理的,所以很难说哪个请求会受影响。
2. 设置 I18n.locale
后,各处都可放心地使用 I18n.locale
。比如在 Model 中给属性加个 wrapper 方法,根据语言返回相应的字段
若要在 controller 中设置 I18n.locale
,各种条件下都要明确设置 I18n.locale
,不要只在满足某些条件时才设置。