# Locale Fallbacks## Extends the I18n module to hold a fallbacks instance which is set to an# instance of I18n::Locale::Fallbacks by default but can be swapped with a# different implementation.## Locale fallbacks will compute a number of fallback locales for a given locale.# For example:## <pre><code># I18n.fallbacks[:"es-MX"] # => [:"es-MX", :es, :en] </code></pre>## Locale fallbacks always fall back to## * all parent locales of a given locale (e.g. :es for :"es-MX") first,# * the current default locales and all of their parents second## The default locales are set to [I18n.default_locale] by default but can be# set to something else.## One can additionally add any number of additional fallback locales manually.# These will be added before the default locales to the fallback chain. For# example:## # using the default locale as default fallback locale## I18n.default_locale = :"en-US"# I18n.fallbacks = I18n::Fallbacks.new(:"de-AT" => :"de-DE")# I18n.fallbacks[:"de-AT"] # => [:"de-AT", :"de-DE", :de, :"en-US", :en]## # using a custom locale as default fallback locale## I18n.fallbacks = I18n::Fallbacks.new(:"en-GB", :"de-AT" => :de, :"de-CH" => :de)# I18n.fallbacks[:"de-AT"] # => [:"de-AT", :de, :"en-GB", :en]# I18n.fallbacks[:"de-CH"] # => [:"de-CH", :de, :"en-GB", :en]## # mapping fallbacks to an existing instance## # people speaking Catalan also speak Spanish as spoken in Spain# fallbacks = I18n.fallbacks# fallbacks.map(:ca => :"es-ES")# fallbacks[:ca] # => [:ca, :"es-ES", :es, :"en-US", :en]## # people speaking Arabian as spoken in Palestine also speak Hebrew as spoken in Israel# fallbacks.map(:"ar-PS" => :"he-IL")# fallbacks[:"ar-PS"] # => [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en]# fallbacks[:"ar-EG"] # => [:"ar-EG", :ar, :"en-US", :en]## # people speaking Sami as spoken in Finnland also speak Swedish and Finnish as spoken in Finnland# fallbacks.map(:sms => [:"se-FI", :"fi-FI"])# fallbacks[:sms] # => [:sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en]moduleI18nmoduleLocaleclassFallbacks<Hashdefinitialize(*mappings)@map={}map(mappings.pop)ifmappings.last.is_a?(Hash)self.defaults=mappings.empty??[I18n.default_locale.to_sym]:mappingsenddefdefaults=(defaults)@defaults=defaults.map{|default|compute(default,false)}.flattenendattr_reader:defaultsdef[](locale)raiseInvalidLocale.new(locale)iflocale.nil?locale=locale.to_symsuper||store(locale,compute(locale))enddefmap(mappings)mappings.eachdo|from,to|from,to=from.to_sym,Array(to)to.eachdo|to|@map[from]||=[]@map[from]<<to.to_symendendendprotecteddefcompute(tags,include_defaults=true)result=Array(tags).collectdo|tag|tags=I18n::Locale::Tag.tag(tag).self_and_parents.map!{|t|t.to_sym}tags.each{|tag|tags+=compute(@map[tag])if@map[tag]}tagsend.flattenresult.push(*defaults)ifinclude_defaultsresult.uniqendendendend