1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class SearchNestedHashByValue def key_for(h, str, trail=[]) h.each_pair do |k, v| if v == str trail << k return true elsif v.is_a?(Hash) return trail if key_for(v, str, trail << k) end end false end end locale_file = {:'sv-SE' => {:lang => 'test', :txt => {:hej => 'hej', :hello => "Hello"}}} s = SearchNestedHashByValue.new puts s.key_for(locale_file, "Hello").join('.') # => sv-SE.txt.hello puts s.key_for(locale_file, "Hell").inspect # => false
Refactorings
No refactoring yet !
Adam
October 8, 2008, October 08, 2008 03:48, permalink
I get the feeling you are reinventing the wheel here. Nevertheless, keeping with what you have:
locale.rb
1 2 3 4 5 6 7 8 9
class Locale < Struct.new(:locale, :language, :text) def include?(string) text.index(string) end def to_key(string) [ locale, language, text.index(string) ].join('.') if include?(string) end end
internationalization.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
class Internationalization def initialize(locale_file) @locales = locale_file.map do |locale,attributes| Locale.new(locale, attributes[:lang], attributes[:txt]) end end def key_for(string) if locale = @locales.find { |locale| locale.include?(string) } locale.to_key(string) else false end end end
Usage
1 2 3 4 5 6
>> i18n = Internationalization.new(locale_file) => #<Internationalization:0x66b48 @locales=[#<struct Locale locale=:"sv-SE", language="test", text={:hello=>"Hello", :hej=>"hej"}>]> >> i18n.key_for("Hello") => "sv-SE.test.hello" >> i18n.key_for("Hell") => false
Search nested hash on their value and return the path as i18n key, aka 'sv-SE.txt.hello'