russian 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,7 +16,7 @@ Russian -- это библиотека для полноценной подде
16
16
 
17
17
  Цель проекта -- построить полноценную среду для русской локализации Ruby и Rails проектов, при этом используя минимально возможное количество хаков, сохраняя при этом поддержку локализации приложения на другие языки, а также форсировать включение в основную ветку I18n и Rails всех функций локализации, необходимых для работы с русским языком.
18
18
 
19
- Russian использует библиотеку I18n (включена в поставку), несколько хаков поверх нее (собственный бекэнд с поддержкой спецефичного для русского форматирования даты и времени, поддержкой плюрализации), несколько хаков поверх Rails (хаки хелперов даты-времени, хак для сообщений валидации) и файлы переводов, а также набор хелперов, упрощающий работу с русским языком (простая плюрализация, простой strftime и др.).
19
+ Russian использует библиотеку I18n (включена в поставку), несколько хаков поверх нее (собственный бекэнд с поддержкой специфичного для русского форматирования даты и времени, поддержкой плюрализации), несколько хаков поверх Rails (хаки хелперов даты-времени, хак для сообщений валидации) и файлы переводов, а также набор хелперов, упрощающий работу с русским языком (простая плюрализация, простой strftime и др.).
20
20
 
21
21
  Russian стремится быть минимально деструктивной для окружения и быть полностью совместимой с другими языками (таким образом, когда приложение использует Russian и собственный бекэнд Russian, оно остается полностью совместимым с Rails i18n).
22
22
 
@@ -92,7 +92,7 @@ h1. Использование
92
92
  * _NB:_ локаль русского языка (@ru-RU@) становится локалью по умолчанию
93
93
  * загружаются все файлы переводов, в том числе переводы для Rails.
94
94
 
95
- После этого можно использовать все стандартные функции библиотеки I18n, пользоваться измененным функицоналом для лучшей поддержки русского языка, или использовать хелперы модуля Russian для еще более простой работы с русским языком.
95
+ После этого можно использовать все стандартные функции библиотеки I18n, пользоваться измененным функционалом для лучшей поддержки русского языка, или использовать хелперы модуля Russian для еще более простой работы с русским языком.
96
96
 
97
97
  h2. Отличия от стандартной библиотеки I18n
98
98
 
@@ -125,7 +125,7 @@ Russian.locale
125
125
  Russian::LOCALE
126
126
  </code></pre>
127
127
 
128
- -- возвращает локаль русского языка (@ru-RU@).
128
+ -- возвращает локаль русского языка (@:'ru-RU'@).
129
129
 
130
130
  <pre><code>
131
131
  Russian::i18n_backend_class
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'rubygems/specification'
5
5
  require 'date'
6
6
 
7
7
  GEM = "russian"
8
- GEM_VERSION = "0.0.6"
8
+ GEM_VERSION = "0.0.7"
9
9
  AUTHOR = "Yaroslav Markin"
10
10
  EMAIL = "yaroslav@markin.net"
11
11
  HOMEPAGE = "http://github.com/yaroslav/russian/"
data/TODO CHANGED
@@ -4,6 +4,7 @@ TODO
4
4
  * check Unicode CLDR to ensure all datetime formats are correct
5
5
  * refactor Advanced backend localize method (looks ugly)
6
6
  * refactor DateTimeSelector#translated_month_names
7
+ * stuff from english gem
7
8
  * Countries list (not in Rails I18n)
8
9
 
9
10
  Questionable
@@ -22,7 +22,7 @@ module Russian
22
22
  module VERSION
23
23
  MAJOR = 0
24
24
  MINOR = 0
25
- TINY = 6
25
+ TINY = 7
26
26
 
27
27
  STRING = [MAJOR, MINOR, TINY].join('.')
28
28
  end
@@ -33,7 +33,6 @@ ru-RU:
33
33
  # These three are to override number.format and are optional
34
34
  # separator:
35
35
  delimiter: ""
36
- precision: 2
37
36
 
38
37
  # Used in number_to_precision()
39
38
  precision:
@@ -43,7 +43,7 @@ ru-RU:
43
43
  greater_than: "может иметь значение большее {{count}}"
44
44
  greater_than_or_equal_to: "может иметь значение большее или равное {{count}}"
45
45
  equal_to: "может иметь лишь значение, равное {{count}}"
46
- less_than: "может иметь значение меньше чем {{count}}"
46
+ less_than: "может иметь значение меньшее чем {{count}}"
47
47
  less_than_or_equal_to: "может иметь значение меньшее или равное {{count}}"
48
48
  odd: "может иметь лишь четное значение"
49
49
  even: "может иметь лишь нечетное значение"
@@ -6,3 +6,4 @@ ru-RU:
6
6
  support:
7
7
  array:
8
8
  sentence_connector: "и"
9
+ skip_last_comma: true
@@ -2,6 +2,8 @@ h1. Ruby I18n gem
2
2
 
3
3
  I18n and localization solution for Ruby.
4
4
 
5
+ For information please refer to http://rails-i18n.org
6
+
5
7
  h2. Authors
6
8
 
7
9
  * "Matt Aimonetti":http://railsontherun.com
@@ -1,24 +1,27 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "i18n"
3
- s.version = "0.0.1"
4
- s.date = "2008-06-13"
5
- s.summary = "Internationalization for Ruby"
6
- s.email = "rails-patch-i18n@googlegroups.com"
7
- s.homepage = "http://groups.google.com/group/rails-patch-i18n"
8
- s.description = "Add Internationalization to your Ruby application."
3
+ s.version = "0.1.0"
4
+ s.date = "2008-10-26"
5
+ s.summary = "Internationalization support for Ruby"
6
+ s.email = "rails-i18n@googlegroups.com"
7
+ s.homepage = "http://rails-i18n.org"
8
+ s.description = "Add Internationalization support to your Ruby application."
9
9
  s.has_rdoc = false
10
- s.authors = ['Sven Fuchs', 'Matt Aimonetti', 'Stephan Soller', 'Saimon Moore']
10
+ s.authors = ['Sven Fuchs', 'Joshua Harvey', 'Matt Aimonetti', 'Stephan Soller', 'Saimon Moore']
11
11
  s.files = [
12
- "lib/i18n/backend/minimal.rb",
13
- "lib/i18n/core_ext.rb",
14
- "lib/i18n/localization.rb",
15
- "lib/i18n/translation.rb",
16
- "lib/i18n.rb",
17
- "LICENSE",
18
- "README",
19
- "spec/core_ext_spec.rb",
20
- "spec/i18n_spec.rb",
21
- "spec/spec.opts",
22
- "spec/spec/helper.rb"
12
+ 'i18n.gemspec',
13
+ 'lib/i18n/backend/simple.rb',
14
+ 'lib/i18n/exceptions.rb',
15
+ 'lib/i18n.rb',
16
+ 'MIT-LICENSE',
17
+ 'README.textile'
18
+ ]
19
+ s.test_files = [
20
+ 'test/all.rb',
21
+ 'test/i18n_exceptions_test.rb',
22
+ 'test/i18n_test.rb',
23
+ 'test/locale/en-US.rb',
24
+ 'test/locale/en-US.yml',
25
+ 'test/simple_backend_test.rb'
23
26
  ]
24
27
  end
@@ -2,39 +2,39 @@
2
2
  # Sven Fuchs (http://www.artweb-design.de),
3
3
  # Joshua Harvey (http://www.workingwithrails.com/person/759-joshua-harvey),
4
4
  # Saimon Moore (http://saimonmoore.net),
5
- # Stephan Soller (http://www.arkanis-development.de/)
5
+ # Stephan Soller (http://www.arkanis-development.de/)
6
6
  # Copyright:: Copyright (c) 2008 The Ruby i18n Team
7
7
  # License:: MIT
8
8
  require 'i18n/backend/simple'
9
9
  require 'i18n/exceptions'
10
10
 
11
- module I18n
11
+ module I18n
12
12
  @@backend = nil
13
- @@load_path = []
13
+ @@load_path = nil
14
14
  @@default_locale = :'en-US'
15
15
  @@exception_handler = :default_exception_handler
16
-
16
+
17
17
  class << self
18
18
  # Returns the current backend. Defaults to +Backend::Simple+.
19
19
  def backend
20
20
  @@backend ||= Backend::Simple.new
21
21
  end
22
-
22
+
23
23
  # Sets the current backend. Used to set a custom backend.
24
- def backend=(backend)
24
+ def backend=(backend)
25
25
  @@backend = backend
26
26
  end
27
-
27
+
28
28
  # Returns the current default locale. Defaults to 'en-US'
29
29
  def default_locale
30
- @@default_locale
30
+ @@default_locale
31
31
  end
32
-
32
+
33
33
  # Sets the current default locale. Used to set a custom default locale.
34
- def default_locale=(locale)
35
- @@default_locale = locale
34
+ def default_locale=(locale)
35
+ @@default_locale = locale
36
36
  end
37
-
37
+
38
38
  # Returns the current locale. Defaults to I18n.default_locale.
39
39
  def locale
40
40
  Thread.current[:locale] ||= default_locale
@@ -44,46 +44,55 @@ module I18n
44
44
  def locale=(locale)
45
45
  Thread.current[:locale] = locale
46
46
  end
47
-
47
+
48
48
  # Sets the exception handler.
49
49
  def exception_handler=(exception_handler)
50
50
  @@exception_handler = exception_handler
51
51
  end
52
-
53
- # Allow clients to register paths providing translation data sources. The
52
+
53
+ # Allow clients to register paths providing translation data sources. The
54
54
  # backend defines acceptable sources.
55
55
  #
56
56
  # E.g. the provided SimpleBackend accepts a list of paths to translation
57
57
  # files which are either named *.rb and contain plain Ruby Hashes or are
58
- # named *.yml and contain YAML data. So for the SimpleBackend clients may
58
+ # named *.yml and contain YAML data. So for the SimpleBackend clients may
59
59
  # register translation files like this:
60
60
  # I18n.load_path << 'path/to/locale/en-US.yml'
61
61
  def load_path
62
- @@load_path
62
+ @@load_path ||= []
63
63
  end
64
64
 
65
+ # Sets the load path instance. Custom implementations are expected to
66
+ # behave like a Ruby Array.
65
67
  def load_path=(load_path)
66
68
  @@load_path = load_path
67
69
  end
68
-
69
- # Translates, pluralizes and interpolates a given key using a given locale,
70
+
71
+ # Tells the backend to reload translations. Used in situations like the
72
+ # Rails development environment. Backends can implement whatever strategy
73
+ # is useful.
74
+ def reload!
75
+ backend.reload!
76
+ end
77
+
78
+ # Translates, pluralizes and interpolates a given key using a given locale,
70
79
  # scope, and default, as well as interpolation values.
71
80
  #
72
81
  # *LOOKUP*
73
82
  #
74
- # Translation data is organized as a nested hash using the upper-level keys
75
- # as namespaces. <em>E.g.</em>, ActionView ships with the translation:
83
+ # Translation data is organized as a nested hash using the upper-level keys
84
+ # as namespaces. <em>E.g.</em>, ActionView ships with the translation:
76
85
  # <tt>:date => {:formats => {:short => "%b %d"}}</tt>.
77
- #
78
- # Translations can be looked up at any level of this hash using the key argument
79
- # and the scope option. <em>E.g.</em>, in this example <tt>I18n.t :date</tt>
86
+ #
87
+ # Translations can be looked up at any level of this hash using the key argument
88
+ # and the scope option. <em>E.g.</em>, in this example <tt>I18n.t :date</tt>
80
89
  # returns the whole translations hash <tt>{:formats => {:short => "%b %d"}}</tt>.
81
- #
82
- # Key can be either a single key or a dot-separated key (both Strings and Symbols
90
+ #
91
+ # Key can be either a single key or a dot-separated key (both Strings and Symbols
83
92
  # work). <em>E.g.</em>, the short format can be looked up using both:
84
93
  # I18n.t 'date.formats.short'
85
94
  # I18n.t :'date.formats.short'
86
- #
95
+ #
87
96
  # Scope can be either a single key, a dot-separated key or an array of keys
88
97
  # or dot-separated keys. Keys and scopes can be combined freely. So these
89
98
  # examples will all look up the same short date format:
@@ -96,9 +105,9 @@ module I18n
96
105
  #
97
106
  # Translations can contain interpolation variables which will be replaced by
98
107
  # values passed to #translate as part of the options hash, with the keys matching
99
- # the interpolation variable names.
108
+ # the interpolation variable names.
100
109
  #
101
- # <em>E.g.</em>, with a translation <tt>:foo => "foo {{bar}}"</tt> the option
110
+ # <em>E.g.</em>, with a translation <tt>:foo => "foo {{bar}}"</tt> the option
102
111
  # value for the key +bar+ will be interpolated into the translation:
103
112
  # I18n.t :foo, :bar => 'baz' # => 'foo baz'
104
113
  #
@@ -107,7 +116,7 @@ module I18n
107
116
  # Translation data can contain pluralized translations. Pluralized translations
108
117
  # are arrays of singluar/plural versions of translations like <tt>['Foo', 'Foos']</tt>.
109
118
  #
110
- # Note that <tt>I18n::Backend::Simple</tt> only supports an algorithm for English
119
+ # Note that <tt>I18n::Backend::Simple</tt> only supports an algorithm for English
111
120
  # pluralization rules. Other algorithms can be supported by custom backends.
112
121
  #
113
122
  # This returns the singular version of a pluralized translation:
@@ -116,9 +125,9 @@ module I18n
116
125
  # These both return the plural version of a pluralized translation:
117
126
  # I18n.t :foo, :count => 0 # => 'Foos'
118
127
  # I18n.t :foo, :count => 2 # => 'Foos'
119
- #
120
- # The <tt>:count</tt> option can be used both for pluralization and interpolation.
121
- # <em>E.g.</em>, with the translation
128
+ #
129
+ # The <tt>:count</tt> option can be used both for pluralization and interpolation.
130
+ # <em>E.g.</em>, with the translation
122
131
  # <tt>:foo => ['{{count}} foo', '{{count}} foos']</tt>, count will
123
132
  # be interpolated to the pluralized translation:
124
133
  # I18n.t :foo, :count => 1 # => '1 foo'
@@ -128,11 +137,11 @@ module I18n
128
137
  # This returns the translation for <tt>:foo</tt> or <tt>default</tt> if no translation was found:
129
138
  # I18n.t :foo, :default => 'default'
130
139
  #
131
- # This returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt> if no
140
+ # This returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt> if no
132
141
  # translation for <tt>:foo</tt> was found:
133
142
  # I18n.t :foo, :default => :bar
134
143
  #
135
- # Returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt>
144
+ # Returns the translation for <tt>:foo</tt> or the translation for <tt>:bar</tt>
136
145
  # or <tt>default</tt> if no translations for <tt>:foo</tt> and <tt>:bar</tt> were found.
137
146
  # I18n.t :foo, :default => [:bar, 'default']
138
147
  #
@@ -148,13 +157,13 @@ module I18n
148
157
  # I18n.t [:foo, :bar], :scope => :baz
149
158
  def translate(key, options = {})
150
159
  locale = options.delete(:locale) || I18n.locale
151
- backend.translate locale, key, options
160
+ backend.translate(locale, key, options)
152
161
  rescue I18n::ArgumentError => e
153
162
  raise e if options[:raise]
154
- send @@exception_handler, e, locale, key, options
155
- end
163
+ send(@@exception_handler, e, locale, key, options)
164
+ end
156
165
  alias :t :translate
157
-
166
+
158
167
  # Localizes certain objects, such as dates and numbers to local formatting.
159
168
  def localize(object, options = {})
160
169
  locale = options[:locale] || I18n.locale
@@ -162,7 +171,7 @@ module I18n
162
171
  backend.localize(locale, object, format)
163
172
  end
164
173
  alias :l :localize
165
-
174
+
166
175
  protected
167
176
  # Handles exceptions raised in the backend. All exceptions except for
168
177
  # MissingTranslationData exceptions are re-raised. When a MissingTranslationData
@@ -172,14 +181,14 @@ module I18n
172
181
  return exception.message if MissingTranslationData === exception
173
182
  raise exception
174
183
  end
175
-
184
+
176
185
  # Merges the given locale, key and scope into a single array of keys.
177
186
  # Splits keys that contain dots into multiple keys. Makes sure all
178
187
  # keys are Symbols.
179
188
  def normalize_translation_keys(locale, key, scope)
180
189
  keys = [locale] + Array(scope) + [key]
181
- keys = keys.map{|k| k.to_s.split(/\./) }
182
- keys.flatten.map{|k| k.to_sym}
190
+ keys = keys.map { |k| k.to_s.split(/\./) }
191
+ keys.flatten.map { |k| k.to_sym }
183
192
  end
184
193
  end
185
- end
194
+ end
@@ -6,42 +6,48 @@ module I18n
6
6
  INTERPOLATION_RESERVED_KEYS = %w(scope default)
7
7
  MATCH = /(\\\\)?\{\{([^\}]+)\}\}/
8
8
 
9
- # Accepts a list of paths to translation files. Loads translations from
9
+ # Accepts a list of paths to translation files. Loads translations from
10
10
  # plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
11
11
  # for details.
12
12
  def load_translations(*filenames)
13
- filenames.each {|filename| load_file filename }
13
+ filenames.each { |filename| load_file(filename) }
14
14
  end
15
-
16
- # Stores translations for the given locale in memory.
15
+
16
+ # Stores translations for the given locale in memory.
17
17
  # This uses a deep merge for the translations hash, so existing
18
18
  # translations will be overwritten by new ones only at the deepest
19
19
  # level of the hash.
20
20
  def store_translations(locale, data)
21
21
  merge_translations(locale, data)
22
22
  end
23
-
23
+
24
24
  def translate(locale, key, options = {})
25
25
  raise InvalidLocale.new(locale) if locale.nil?
26
- return key.map{|k| translate locale, k, options } if key.is_a? Array
26
+ return key.map { |k| translate(locale, k, options) } if key.is_a? Array
27
27
 
28
28
  reserved = :scope, :default
29
29
  count, scope, default = options.values_at(:count, *reserved)
30
30
  options.delete(:default)
31
- values = options.reject{|name, value| reserved.include? name }
31
+ values = options.reject { |name, value| reserved.include?(name) }
32
32
 
33
- entry = lookup(locale, key, scope) || default(locale, default, options) || raise(I18n::MissingTranslationData.new(locale, key, options))
34
- entry = pluralize locale, entry, count
35
- entry = interpolate locale, entry, values
33
+ entry = lookup(locale, key, scope)
34
+ if entry.nil?
35
+ entry = default(locale, default, options)
36
+ if entry.nil?
37
+ raise(I18n::MissingTranslationData.new(locale, key, options))
38
+ end
39
+ end
40
+ entry = pluralize(locale, entry, count)
41
+ entry = interpolate(locale, entry, values)
36
42
  entry
37
43
  end
38
-
39
- # Acts the same as +strftime+, but returns a localized version of the
40
- # formatted date string. Takes a key from the date/time formats
41
- # translations as a format argument (<em>e.g.</em>, <tt>:short</tt> in <tt>:'date.formats'</tt>).
44
+
45
+ # Acts the same as +strftime+, but returns a localized version of the
46
+ # formatted date string. Takes a key from the date/time formats
47
+ # translations as a format argument (<em>e.g.</em>, <tt>:short</tt> in <tt>:'date.formats'</tt>).
42
48
  def localize(locale, object, format = :default)
43
49
  raise ArgumentError, "Object must be a Date, DateTime or Time object. #{object.inspect} given." unless object.respond_to?(:strftime)
44
-
50
+
45
51
  type = object.respond_to?(:sec) ? 'time' : 'date'
46
52
  # TODO only translate these if format is a String?
47
53
  formats = translate(locale, :"#{type}.formats")
@@ -51,56 +57,70 @@ module I18n
51
57
 
52
58
  # TODO only translate these if the format string is actually present
53
59
  # TODO check which format strings are present, then bulk translate then, then replace them
54
- format.gsub!(/%a/, translate(locale, :"date.abbr_day_names")[object.wday])
60
+ format.gsub!(/%a/, translate(locale, :"date.abbr_day_names")[object.wday])
55
61
  format.gsub!(/%A/, translate(locale, :"date.day_names")[object.wday])
56
62
  format.gsub!(/%b/, translate(locale, :"date.abbr_month_names")[object.mon])
57
63
  format.gsub!(/%B/, translate(locale, :"date.month_names")[object.mon])
58
64
  format.gsub!(/%p/, translate(locale, :"time.#{object.hour < 12 ? :am : :pm}")) if object.respond_to? :hour
59
65
  object.strftime(format)
60
66
  end
61
-
67
+
68
+ def initialized?
69
+ @initialized ||= false
70
+ end
71
+
72
+ def reload!
73
+ @initialized = false
74
+ @translations = nil
75
+ end
76
+
62
77
  protected
63
-
64
78
  def init_translations
65
79
  load_translations(*I18n.load_path)
66
80
  @initialized = true
67
81
  end
68
-
82
+
69
83
  def translations
70
84
  @translations ||= {}
71
85
  end
72
-
73
- # Looks up a translation from the translations hash. Returns nil if
86
+
87
+ # Looks up a translation from the translations hash. Returns nil if
74
88
  # eiher key is nil, or locale, scope or key do not exist as a key in the
75
89
  # nested translations hash. Splits keys or scopes containing dots
76
90
  # into multiple keys, i.e. <tt>currency.format</tt> is regarded the same as
77
91
  # <tt>%w(currency format)</tt>.
78
92
  def lookup(locale, key, scope = [])
79
93
  return unless key
80
- init_translations unless @initialized
81
- keys = I18n.send :normalize_translation_keys, locale, key, scope
82
- keys.inject(translations){|result, k| result[k.to_sym] or return nil }
94
+ init_translations unless initialized?
95
+ keys = I18n.send(:normalize_translation_keys, locale, key, scope)
96
+ keys.inject(translations) do |result, k|
97
+ if (x = result[k.to_sym]).nil?
98
+ return nil
99
+ else
100
+ x
101
+ end
102
+ end
83
103
  end
84
-
85
- # Evaluates a default translation.
104
+
105
+ # Evaluates a default translation.
86
106
  # If the given default is a String it is used literally. If it is a Symbol
87
107
  # it will be translated with the given options. If it is an Array the first
88
108
  # translation yielded will be returned.
89
- #
90
- # <em>I.e.</em>, <tt>default(locale, [:foo, 'default'])</tt> will return +default+ if
109
+ #
110
+ # <em>I.e.</em>, <tt>default(locale, [:foo, 'default'])</tt> will return +default+ if
91
111
  # <tt>translate(locale, :foo)</tt> does not yield a result.
92
112
  def default(locale, default, options = {})
93
113
  case default
94
114
  when String then default
95
115
  when Symbol then translate locale, default, options
96
- when Array then default.each do |obj|
116
+ when Array then default.each do |obj|
97
117
  result = default(locale, obj, options.dup) and return result
98
118
  end and nil
99
119
  end
100
120
  rescue MissingTranslationData
101
121
  nil
102
122
  end
103
-
123
+
104
124
  # Picks a translation from an array according to English pluralization
105
125
  # rules. It will pick the first translation if count is not equal to 1
106
126
  # and the second translation if it is equal to 1. Other backends can
@@ -113,20 +133,18 @@ module I18n
113
133
  raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
114
134
  entry[key]
115
135
  end
116
-
136
+
117
137
  # Interpolates values into a given string.
118
- #
119
- # interpolate "file {{file}} opened by \\{{user}}", :file => 'test.txt', :user => 'Mr. X'
138
+ #
139
+ # interpolate "file {{file}} opened by \\{{user}}", :file => 'test.txt', :user => 'Mr. X'
120
140
  # # => "file test.txt opened by {{user}}"
121
- #
141
+ #
122
142
  # Note that you have to double escape the <tt>\\</tt> when you want to escape
123
143
  # the <tt>{{...}}</tt> key in a string (once for the string and once for the
124
144
  # interpolation).
125
145
  def interpolate(locale, string, values = {})
126
146
  return string unless string.is_a?(String)
127
147
 
128
- string = string.gsub(/%d/, '{{count}}').gsub(/%s/, '{{value}}')
129
-
130
148
  if string.respond_to?(:force_encoding)
131
149
  original_encoding = string.encoding
132
150
  string.force_encoding(Encoding::BINARY)
@@ -149,45 +167,45 @@ module I18n
149
167
  result.force_encoding(original_encoding) if original_encoding
150
168
  result
151
169
  end
152
-
153
- # Loads a single translations file by delegating to #load_rb or
170
+
171
+ # Loads a single translations file by delegating to #load_rb or
154
172
  # #load_yml depending on the file extension and directly merges the
155
173
  # data to the existing translations. Raises I18n::UnknownFileType
156
174
  # for all other file extensions.
157
175
  def load_file(filename)
158
176
  type = File.extname(filename).tr('.', '').downcase
159
- raise UnknownFileType.new(type, filename) unless respond_to? :"load_#{type}"
177
+ raise UnknownFileType.new(type, filename) unless respond_to?(:"load_#{type}")
160
178
  data = send :"load_#{type}", filename # TODO raise a meaningful exception if this does not yield a Hash
161
- data.each{|locale, d| merge_translations locale, d }
179
+ data.each { |locale, d| merge_translations(locale, d) }
162
180
  end
163
-
181
+
164
182
  # Loads a plain Ruby translations file. eval'ing the file must yield
165
183
  # a Hash containing translation data with locales as toplevel keys.
166
184
  def load_rb(filename)
167
- eval IO.read(filename), binding, filename
185
+ eval(IO.read(filename), binding, filename)
168
186
  end
169
-
170
- # Loads a YAML translations file. The data must have locales as
187
+
188
+ # Loads a YAML translations file. The data must have locales as
171
189
  # toplevel keys.
172
190
  def load_yml(filename)
173
- YAML::load IO.read(filename)
191
+ YAML::load(IO.read(filename))
174
192
  end
175
-
193
+
176
194
  # Deep merges the given translations hash with the existing translations
177
195
  # for the given locale
178
196
  def merge_translations(locale, data)
179
197
  locale = locale.to_sym
180
198
  translations[locale] ||= {}
181
- data = deep_symbolize_keys data
199
+ data = deep_symbolize_keys(data)
182
200
 
183
201
  # deep_merge by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
184
- merger = proc{|key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
185
- translations[locale].merge! data, &merger
202
+ merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
203
+ translations[locale].merge!(data, &merger)
186
204
  end
187
-
205
+
188
206
  # Return a new hash with all keys and nested keys converted to symbols.
189
207
  def deep_symbolize_keys(hash)
190
- hash.inject({}){|result, (key, value)|
208
+ hash.inject({}) { |result, (key, value)|
191
209
  value = deep_symbolize_keys(value) if value.is_a? Hash
192
210
  result[(key.to_sym rescue key) || key] = value
193
211
  result
@@ -195,4 +213,4 @@ module I18n
195
213
  end
196
214
  end
197
215
  end
198
- end
216
+ end