Search code examples
ruby-on-railsrails-i18n

Why I18n translations change when local variable with a selected translation key changes?


This is above me today. Hope someone can explain this to me!

Assume you have a rails project with a en.yml file with the following contents:

en:
  foo:
    foo: foo
    bar: bar

Assigning the results of I18n.t(:foo) to a local variable, you get a Hash:

2.0.0-p353 :001 > a = I18n.t(:foo)
 => {:foo=>"foo", :bar=>"bar"}

And now, changing a value for a key in this Hash causes changes in I18n.t('foo.foo'):

2.0.0-p353 :005 >   a[:foo] = 'bar'
 => "bar" 
2.0.0-p353 :006 > I18n.t(:foo)
 => {:foo=>"bar", :bar=>"bar"} 

So, for the question to be clear - why changing a[:foo] from 'foo' to 'bar', causes the changes in I18n.t('foo.foo')?

Thanks in advance!


Solution

  • After

    a = I18n.t(:foo)
    

    The reference a does not hold a copy, but reference to the same Hash. Altering the Hash at a modifies the same Hash at I18n.t(:foo).

    This is not special behavior of I18n.t, rather this is normal behavior for Ruby.

    > a
    => {:foo=>:bar, :baz=>:qux}
    > b = a
    => {:foo=>:bar, :baz=>:qux}
    > b[:foo] = 1
    => 1
    > b
    => {:foo=>1, :baz=>:qux}
    > a
    => {:foo=>1, :baz=>:qux}