A4d90c6fe98bfe0b491c277c3e687031

Search nested hash on their value and return the path as i18n key, aka 'sv-SE.txt.hello'

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 !

A8d3f35baafdaea851914b17dae9e1fc

Adam

October 8, 2008, October 08, 2008 03:48, permalink

No rating. Login to rate!

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

Your refactoring





Format Copy from initial code

or Cancel