# "private method \`gsub'" error caused by addition of a line

**URL:** <https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237>\
**Category:** Rails I18n\
**Created:** [April 20, 2010, 12:12pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237 "2010-04-20T12:12:39Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 20, 2010, 12:12pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/1 "2010-04-20T12:12:39Z")

</div>

hi all. I just added this line to my config/locals/en.yml file and now  
rails is blowing up when i try to start mongrel/console.

old version:

title:  
main: Who Wants To Be A Millionaire? For Schools

flashes:  
quiz:  
saved: Your quiz has been saved

new version:

title:  
main: Who Wants To Be A Millionaire? For Schools

taggings:  
create\_failed: “Could not add this tag because {{message}}”

flashes:  
quiz:  
saved: Your quiz has been saved

error:  
/usr/lib/ruby/1.8/uri/common.rb:289:in `escape': private method`gsub’  
called for {:create\_failed=\>“Could not add this tag because”}:Hash  
(NoMethodError)

I tried it without the quotes originally and it blew up. It still blows  
up if i remove the quotes and the the variable part, ie this still  
causes the error:

taggings:  
create\_failed: Could not add this tag because

I don’t understand what’s gone wrong here. If i delete the line then  
it’s fine, but what’s wrong with this line? As far as i can tell  
there’s nothing in there that would break the formatting syntax.

any ideas welcomed…thanks, max

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 20, 2010, 3:04pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/2 "2010-04-20T15:04:12Z")

</div>

Can you show your view, please

2010/4/20 Max W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 20, 2010, 3:22pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/3 "2010-04-20T15:22:04Z")

</div>

AndrÃ©s GutiÃ©rrez wrote:

> Can you show your view, please
> 
> 2010/4/20 Max W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

Hi andres - it’s not my view that’s at fault (and it’s actually called  
from a controller action as it happens) - i can’t even start the app.  
Rails is blowing up when it tries to parse the en.yml file.

What’s weird is if i nest it inside another block, eg change it to this

title:  
main: Who Wants To Be A Millionaire? For Schools

flashes:  
taggings:  
save\_failed: Could not add this tag because {{message}}  
quiz:  
saved: Your quiz has been saved

then it’s fine. But if i change it back to this:

title:  
main: Who Wants To Be A Millionaire? For Schools

taggings:  
save\_failed: Could not add this tag because {{message}}

flashes:  
quiz:  
saved: Your quiz has been saved

then i get the error:  
/usr/lib/ruby/1.8/uri/common.rb:289:in `escape': private method `gsub’  
called for {:save\_failed=\>“Could not add this tag because  
{{message}}”}:Hash (NoMethodError)

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 20, 2010, 3:40pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/4 "2010-04-20T15:40:15Z")

</div>

AndrÃ©s GutiÃ©rrez wrote:

> well, can you show me your controller? 🙂
> 
> 2010/4/20 Max W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

Well, yes, but i promise you that it is irrelevant to the problem since  
the controller code is not executed before the problem occurs!

def create\_tagging  
@taggable =  
params[:tagging][:taggable\_type].constantize.find(params[:tagging][:taggable\_id])  
@tagging = @taggable.tag\_with(params[:tagging][:tag\_name], :user\_id  
=\> params[:tagging][:user\_id])  
unless @tagging && @tagging.id  
add\_error t(‘taggings.save\_failed’, :message =\>  
@tagging.errors.full\_messages.join(", "))  
end  
end

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 20, 2010, 4:06pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/5 "2010-04-20T16:06:15Z")

</div>

Sorry, but what is "add\_error "? is a rails method? or what?

2010/4/20 Max W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 20, 2010, 3:28pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/6 "2010-04-20T15:28:48Z")

</div>

well, can you show me your controller? 🙂

2010/4/20 Max W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 20, 2010, 4:17pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/7 "2010-04-20T16:17:33Z")

</div>

AndrÃ©s GutiÃ©rrez wrote:

> Sorry, but what is "add\_error "? is a rails method? or what?
> 
> 2010/4/20 Max W. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

it’s effectively a way of putting something into flash[:error], it’s  
from a plugin called “flash-message-conductor”. But, at the risk of  
sounding like a broken record, the actually call to I18n.t isn’t the  
issue, since the app breaks as soon as i try to start it, NOT when the  
translate call is made.

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 20, 2010, 7:55pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/8 "2010-04-20T19:55:14Z")

</div>

Can you reproduce your error with a fresh new Rails application with the  
same en.yml?

If so, could you send the entire en.yml and tell us your Rails version?

I guess you mean “config/locales/en.yml” instead of  
“config/locals/en.yml”, right?

Really strange issue…

Rodrigo.

Em 20-04-2010 11:17, Max W. escreveu:

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 20, 2010, 11:04pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/9 "2010-04-20T23:04:22Z")

</div>

Could you reduce it to an absolutely minimal failing yml file?

Perhaps the issue is something like a non-breaking space instead of a  
regular space. No idea what errors that would give, if any.

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 21, 2010, 10:40am UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/10 "2010-04-21T10:40:36Z")

</div>

Rodrigo Rosenfeld R. wrote:

> Can you reproduce your error with a fresh new Rails application with the  
> same en.yml?

Hi Rodrigo

I’ve done as you suggested:

1. i made a new rails app ‘foo’

2. In my new app ‘foo’ i uncommented the following in my environment.rb

athough as a side note, this line, when commented, said

Dir[Rails.root.join(‘my’, ‘locales’

… which seems weird - does locales live in a ‘my’ folder by default,  
rather than ‘config’??

1. Anyway, i set up the new app, with the above line, copied my en.yml  
file into locales, started the app, fine.

2. Set up a basic route / to the welcome controller, made the welcome  
controller and views/welcome/index.html.erb, which calls t, deleted  
public/index.html and started the app. Fine.

3. The page loads fine and the translation works, with the problematic  
line back in the position that was making it break before.

What’s weird is if i now deliberately break the syntax of en.yml, eg by  
shoving a : in on it’s own line, i only get the complaint when i make  
the t call, NOT when the app starts, as is the case in my other app. In  
other words, if i add a spurious : to the en.yml in my ‘proper’ rails  
app it blows up as soon as i start mongrel.

I don’t know what the difference would be between them. One possible  
thing is that in my ‘proper’ rails app i have frozen rails and all of  
the gems i use into the vendor folder. Would this have anything to do  
with it do you think?

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 21, 2010, 10:47am UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/11 "2010-04-21T10:47:57Z")

</div>

err “hi henrik” that should have read. Finger problem rather than eye  
problem 🙂

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 21, 2010, 10:46am UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/12 "2010-04-21T10:46:38Z")

</div>

Hi Henri, thanks.

Yes, i’ve took out everything else and it still breaks, which should  
make diagnosis easier. I too suspected it might be some kind of rogue  
invisible character breaking it so rather than copy the text into my  
post, here’s a download link for the actual file (i copied it into my  
public dropbox)

[http://dl.dropbox.com/u/846812/en.yml](http://dl.dropbox.com/u/846812/en.yml)

Is there a nice way in bash/linux to view the contents of a file showing  
all of the formatting characters?

thanks again, max

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 21, 2010, 3:24pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/13 "2010-04-21T15:24:55Z")

</div>

Hi Max.

Please note this comment in a new fresh Rails app:

# The default locale is :en and all translations from

config/locales/\*.rb,yml are auto loaded.

It means you don’t need to uncomment the following lines if you will be  
setting default\_locale to :en and put your translations into  
config/locales, following Rails conventions.

About your problem, as I suspected before, it is not related to the  
locale file itself, but some other code being loaded on Rails startup.  
Could you send the stacktrace so we can help you better?

You could try disable your plugins and moving your scripts in  
config/initializers to other place to see if the error disappears.

I would start from the stacktrace, then would probably debug the  
relevant part where it is breaking to see what is happening.

You can also turn your plugins back one by one if the errors disappear  
when you disable all your plugins. Same for the initializers scripts.

> I don’t know what the difference would be between them. One possible  
> thing is that in my ‘proper’ rails app i have frozen rails and all of  
> the gems i use into the vendor folder. Would this have anything to do  
> with it do you think?

I don’t think this make any differences here, but you can freeze your  
new Rails app as well if you think this might be a problem…

Good luck,

Rodrigo.

Em 21-04-2010 05:40, Max W. escreveu:

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 22, 2010, 3:53am UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/14 "2010-04-22T03:53:14Z")

</div>

Em 21-04-2010 11:44, Max W. escreveu:

> into routes to give you translated urls? I should have guessed this
> 
> flashes:  
> (i’m guessing “taggings” is the default). So, it calls gsub on it,  
> it’s a hash rather than a string, and you get the error because you  
> can’t call gsub on a hash (it’s a private method).
> 
> That’s also why indenting it to be under flashes was fine: it doesn’t  
> fight with the default top level “taggings” key any more and there’s no  
> problem.
> 
> Does that make sense? I’m not sure if i explained it well.

Completely, you stated it very clear.

Maybe you should add this note to Rails I18n API and as a comment in the  
en.yml template, besides stating this behavior in the Rails guides. All  
through the railsdoc project. What do you say? This breaks the least  
surprise principle, I guess… 🙂

Best regards,

Rodrigo.

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 21, 2010, 4:44pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/15 "2010-04-21T16:44:40Z")

</div>

I think i found what is causing it, and if i’m right it’s a gotcha of  
the highest order. The rule seems to be

“In your .yml file you cannot have a top-level key which has the  
same name as one of your controllers and which points to a further  
nested set of key-value pairs”

It seems that the controller names (or maybe resource names from  
routes.rb) are pushed into the hash of translated terms automatically,  
as part of the general mechanism of I18n - i guess this is what hooks  
into routes to give you translated urls? I should have guessed this  
before because i noticed that if i had these as top-level pairs in my  
en.yml file:

en:  
#url translations  
users: users  
account: account  
quizzes: quizzes  
questions: questions  
user\_session: user\_session

these are all controllers in my app, and i automatically get translated  
urls without having to do anything, if the urls contain these words. I  
also have a taggings controller, so when i had this:

title:  
main: Who Wants To Be A Millionaire? For Schools

taggings:  
save\_failed: Could not add this tag because {{message}}

flashes:  
quiz:  
saved: Your quiz has been saved

…the part that was breaking was that i added a top level key,  
“taggings”, which points to another hash {“save\_failed” =\> “Could not  
add this tag because {{message}}”}. The actual bug was caused because  
rails was expecting this to be a string, probably because of the  
automatically added entry for “taggings” which DOES point to a string  
(i’m guessing “taggings” is the default). So, it calls gsub on it,  
it’s a hash rather than a string, and you get the error because you  
can’t call gsub on a hash (it’s a private method).

That’s also why indenting it to be under flashes was fine: it doesn’t  
fight with the default top level “taggings” key any more and there’s no  
problem.

Does that make sense? I’m not sure if i explained it well.

So, another way to state my rule is:

“Controller names CAN be used as top level keys, and must point to a  
simple value rather than another hash. If present, these will be  
translated in urls.”

or

“If you have a top level key which is the same name as one of your  
controllers/resources, and it has further nested translations below it,  
kiss your app goodbye”

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 22, 2010, 11:30am UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/16 "2010-04-22T11:30:25Z")

</div>

So to put it in other words, your keys were doubly defined, like this:

en:  
foo: bar  
foo:  
baz: bang

And YAML being as it is (a hash), it allows for only one unique key,  
so one of them wins.  
When I18n receives a string instead of a hash for nested translation  
keys (or the other way round) it gives strange errors.

A problem can arise with default translations, provided by gems or  
rails itself, which you know nothing about, that get added to the  
I18n.load\_paths.  
You cannot see the duplication because it’s spread around different  
files, sometimes tucked away inside a gem.

A solution might be something that checks the translations for doubled  
keys, although I think this is tricky to make.  
Another solution might be that I18n gives a more sensible error (or  
doesn’t try to interpolate when it’s not a string)

Am I formulating this right?

Iain

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 22, 2010, 11:56am UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/17 "2010-04-22T11:56:56Z")

</div>

Yeah, ultimately the problem was that the ‘tagging’ key was double  
defined - one pointed to a string and the other pointed to a hash. The  
tricky part was that i only defined the pointing-to-a-hash version in my  
yaml file, and the pointing-to-a-string one was invisibly added by  
rails. This is the gotcha part.

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 22, 2010, 11:59am UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/18 "2010-04-22T11:59:00Z")

</div>

And yes, it would be good if I18n didn’t blow up but instead just  
‘chose’ one of them. To me the most sensible approach would be that  
keys explicitly defined in the yaml override anything invisbly added by  
rails/I18n/plugins/gems etc.

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 22, 2010, 10:18am UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/19 "2010-04-22T10:18:54Z")

</div>

Hi Rodrigo, i will, it’d be nice to give something back for a change.

thanks a lot  
max

---

<div class="post-metadata">

**Author:** ![cmaxvv](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/85f322/32.png) [@cmaxvv](https://www.ruby-forum.com/u/cmaxvv)\
**Post date:** [April 22, 2010, 1:40pm UTC](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237/20 "2010-04-22T13:40:59Z")

</div>

Iain H. wrote:

> The problem is that I18n can’t choose anything, because when the file  
> is read, the second one overwrites the first one. This is done outside  
> I18n.  
> It’s logical too, because you’re actually saying something like this:  
> { :foo =\> 1, :foo =\> 2 } which will always result in { :foo =\> 2 }.
> 
> Gem authors should put their locales in front of the load\_paths, so  
> that the locales from gems are overwritten by your own locales.

right, yeah. Is there any way i can make that happen in my  
environment.rb do you know? In this case it’s not a problem, i’m just  
wondering for the future.

[Next page](https://www.ruby-forum.com/t/private-method-gsub-error-caused-by-addition-of-a-line/187237.md?page=2)
