Skip to content
This repository
Browse code

Move I18n configuration to I18n.config.

  • Loading branch information...
commit 4a7baea86663ead8c681008c3e80a622f0546b07 1 parent 32aafb0
José Valim authored March 10, 2010
79  lib/i18n.rb
@@ -15,13 +15,18 @@ module I18n
15 15
   autoload :Helpers, 'i18n/helpers'
16 16
   autoload :Locale,  'i18n/locale'
17 17
 
18  
-  @@backend = nil
19  
-  @@load_path = nil
20  
-  @@default_locale = :en
21  
-  @@default_separator = '.'
22  
-  @@exception_handler = :default_exception_handler
  18
+  class Config
  19
+    # The only configuration value that is not global and scoped to thread is :locale.
  20
+    # It defaults to the default_locale.
  21
+    def locale
  22
+      @locale ||= default_locale
  23
+    end
  24
+
  25
+    # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
  26
+    def locale=(locale)
  27
+      @locale = locale.to_sym rescue nil
  28
+    end
23 29
 
24  
-  class << self
25 30
     # Returns the current backend. Defaults to +Backend::Simple+.
26 31
     def backend
27 32
       @@backend ||= Backend::Simple.new
@@ -34,7 +39,7 @@ def backend=(backend)
34 39
 
35 40
     # Returns the current default locale. Defaults to :'en'
36 41
     def default_locale
37  
-      @@default_locale
  42
+      @@default_locale ||= :en
38 43
     end
39 44
 
40 45
     # Sets the current default locale. Used to set a custom default locale.
@@ -42,16 +47,6 @@ def default_locale=(locale)
42 47
       @@default_locale = locale.to_sym rescue nil
43 48
     end
44 49
 
45  
-    # Returns the current locale. Defaults to I18n.default_locale.
46  
-    def locale
47  
-      Thread.current[:locale] ||= default_locale
48  
-    end
49  
-
50  
-    # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
51  
-    def locale=(locale)
52  
-      Thread.current[:locale] = locale.to_sym rescue nil
53  
-    end
54  
-
55 50
     # Returns an array of locales for which translations are available.
56 51
     # Unless you explicitely set the these through I18n.available_locales=
57 52
     # the call will be delegated to the backend and memoized on the I18n module.
@@ -66,7 +61,7 @@ def available_locales=(locales)
66 61
 
67 62
     # Returns the current default scope separator. Defaults to '.'
68 63
     def default_separator
69  
-      @@default_separator
  64
+      @@default_separator ||= '.'
70 65
     end
71 66
 
72 67
     # Sets the current default scope separator.
@@ -74,6 +69,11 @@ def default_separator=(separator)
74 69
       @@default_separator = separator
75 70
     end
76 71
 
  72
+    # Return the current exception handler. Defaults to :default_exception_handler.
  73
+    def exception_handler
  74
+      @@exception_handler ||= :default_exception_handler
  75
+    end
  76
+
77 77
     # Sets the exception handler.
78 78
     def exception_handler=(exception_handler)
79 79
       @@exception_handler = exception_handler
@@ -96,12 +96,39 @@ def load_path
96 96
     def load_path=(load_path)
97 97
       @@load_path = load_path
98 98
     end
  99
+  end
  100
+
  101
+  class << self
  102
+
  103
+    # Gets I18n configuration object.
  104
+    def config
  105
+      Thread.current[:i18n_config] ||= I18n::Config.new
  106
+    end
  107
+
  108
+    # Sets I18n configuration object.
  109
+    def config=(value)
  110
+      Thread.current[:i18n_config] = value
  111
+    end
  112
+
  113
+    # Write methods which delegates to the configuration object
  114
+    %w(locale backend default_locale available_locales default_separator
  115
+      exception_handler load_path).each do |method|
  116
+      module_eval <<-DELEGATORS, __FILE__, __LINE__ + 1
  117
+        def #{method}
  118
+          config.#{method}
  119
+        end
  120
+
  121
+        def #{method}=(value)
  122
+          config.#{method} = (value)
  123
+        end
  124
+      DELEGATORS
  125
+    end
99 126
 
100 127
     # Tells the backend to reload translations. Used in situations like the
101 128
     # Rails development environment. Backends can implement whatever strategy
102 129
     # is useful.
103 130
     def reload!
104  
-      backend.reload!
  131
+      config.backend.reload!
105 132
     end
106 133
 
107 134
     # Translates, pluralizes and interpolates a given key using a given locale,
@@ -203,9 +230,9 @@ def reload!
203 230
     def translate(*args)
204 231
       options = args.pop if args.last.is_a?(Hash)
205 232
       key     = args.shift
206  
-      locale  = options && options.delete(:locale) || I18n.locale
  233
+      locale  = options && options.delete(:locale) || config.locale
207 234
       raises  = options && options.delete(:raise)
208  
-      backend.translate(locale, key, options || {})
  235
+      config.backend.translate(locale, key, options || {})
209 236
     rescue I18n::ArgumentError => exception
210 237
       raise exception if raises
211 238
       handle_exception(exception, locale, key, options)
@@ -219,9 +246,9 @@ def translate!(key, options = {})
219 246
 
220 247
     # Localizes certain objects, such as dates and numbers to local formatting.
221 248
     def localize(object, options = {})
222  
-      locale = options.delete(:locale) || I18n.locale
  249
+      locale = options.delete(:locale) || config.locale
223 250
       format = options.delete(:format) || :default
224  
-      backend.localize(locale, object, format, options)
  251
+      config.backend.localize(locale, object, format, options)
225 252
     end
226 253
     alias :l :localize
227 254
 
@@ -266,11 +293,11 @@ def default_exception_handler(exception, locale, key, options)
266 293
     #  I18n.exception_handler = I18nExceptionHandler.new                # an object
267 294
     #  I18n.exception_handler.call(exception, locale, key, options)     # will be called like this
268 295
     def handle_exception(exception, locale, key, options)
269  
-      case @@exception_handler
  296
+      case config.exception_handler
270 297
       when Symbol
271  
-        send(@@exception_handler, exception, locale, key, options)
  298
+        send(config.exception_handler, exception, locale, key, options)
272 299
       else
273  
-        @@exception_handler.call(exception, locale, key, options)
  300
+        config.exception_handler.call(exception, locale, key, options)
274 301
       end
275 302
     end
276 303
 
39  test/i18n_test.rb
@@ -21,6 +21,7 @@ def test_uses_simple_backend_set_by_default
21 21
   def test_can_set_backend
22 22
     assert_nothing_raised { I18n.backend = self }
23 23
     assert_equal self, I18n.backend
  24
+  ensure
24 25
     I18n.backend = I18n::Backend::Simple.new
25 26
   end
26 27
 
@@ -31,6 +32,7 @@ def test_uses_en_us_as_default_locale_by_default
31 32
   def test_can_set_default_locale
32 33
     assert_nothing_raised { I18n.default_locale = 'de' }
33 34
     assert_equal :de, I18n.default_locale
  35
+  ensure
34 36
     I18n.default_locale = :en
35 37
   end
36 38
 
@@ -41,16 +43,47 @@ def test_uses_default_locale_as_locale_by_default
41 43
   def test_can_set_locale_to_thread_current
42 44
     assert_nothing_raised { I18n.locale = 'de' }
43 45
     assert_equal :de, I18n.locale
44  
-    assert_equal :de, Thread.current[:locale]
  46
+    assert_equal :de, Thread.current[:i18n_config].locale
45 47
     I18n.locale = :en
46 48
   end
47 49
 
  50
+  def test_can_set_i18n_config
  51
+    I18n.config = self
  52
+    assert_equal self, I18n.config
  53
+    assert_equal self, Thread.current[:i18n_config]
  54
+  ensure
  55
+    I18n.config = ::I18n::Config.new
  56
+  end
  57
+
  58
+  def test_locale_is_not_shared_between_configurations
  59
+    a = I18n::Config.new
  60
+    b = I18n::Config.new
  61
+    a.locale = :fr
  62
+    b.locale = :es
  63
+    assert_equal :fr, a.locale
  64
+    assert_equal :es, b.locale
  65
+    assert_equal :en, I18n.locale
  66
+  end
  67
+
  68
+  def test_other_options_are_shared_between_configurations
  69
+    a = I18n::Config.new
  70
+    b = I18n::Config.new
  71
+    a.default_locale = :fr
  72
+    b.default_locale = :es
  73
+    assert_equal :es, a.default_locale
  74
+    assert_equal :es, b.default_locale
  75
+    assert_equal :es, I18n.default_locale
  76
+  ensure
  77
+    I18n.default_locale = :en
  78
+  end
  79
+
48 80
   def test_defaults_to_dot_as_separator
49 81
     assert_equal '.', I18n.default_separator
50 82
   end
51 83
 
52 84
   def test_can_set_default_separator
53 85
     assert_nothing_raised { I18n.default_separator = "\001" }
  86
+  ensure
54 87
     I18n.default_separator = '.' # revert it
55 88
   end
56 89
 
@@ -73,7 +106,8 @@ def test_uses_passed_separator_to_normalize_keys
73 106
 
74 107
   def test_can_set_exception_handler
75 108
     assert_nothing_raised { I18n.exception_handler = :custom_exception_handler }
76  
-    I18n.exception_handler = :default_exception_handler # revert it
  109
+  ensure
  110
+    I18n.exception_handler = :default_exception_handler
77 111
   end
78 112
 
79 113
   with_mocha do
@@ -81,6 +115,7 @@ def test_uses_custom_exception_handler
81 115
       I18n.exception_handler = :custom_exception_handler
82 116
       I18n.expects(:custom_exception_handler)
83 117
       I18n.translate :bogus
  118
+    ensure
84 119
       I18n.exception_handler = :default_exception_handler # revert it
85 120
     end
86 121
 

0 notes on commit 4a7baea

Please sign in to comment.
Something went wrong with that request. Please try again.