Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
I18n translation with Integers for map keys


I18n uses YAML files to store translations, however when using an integer as a map key, the translation is then missing when referenced. This may be unexpected at first, but below describes the translation process, and why it is happening.

Sample YAML file

    foo: 'bar'


I18n.translate('') #=> "translation missing:"

We might have expected 'bar'

The Problem

  • I18n.translate calls
  • lookup calls
  • I18n.normalize_keys (i18n-0.6.1/lib/i18n.rb:255) calls
  • normalize_key (i18n-0.6.1/lib/i18n.rb:303)

The normalize_key method is shown below:

def normalize_key(key, separator)
  normalized_key_cache[separator][key] ||=
    case key
    when Array { |k| normalize_key(k, separator) }.flatten
      keys = key.to_s.split(separator)
      keys.delete('')! { |k| k.to_sym }

Note that this calls key.to_s followed by .to_sym. e.g. normalize_key("", ".") # => [:"1", :foo]

The translation file is loaded in the lookup method at this time with the key preserved in Integer format. However our lookup key is now: key.to_s.to_sym They integer map key is converted to a symbol, however we are now comparing :"1" with "1" and the translation fails because the key is missing.


Even though YAML supports Integers as map keys - use string representations of Integers as map keys when using I18n

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.