activesupport 2.3.8 → 2.3.9.pre

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (66) hide show
  1. data/CHANGELOG +11 -0
  2. data/lib/active_support/core_ext/array/grouping.rb +1 -1
  3. data/lib/active_support/core_ext/array/random_access.rb +24 -4
  4. data/lib/active_support/core_ext/class.rb +1 -0
  5. data/lib/active_support/core_ext/class/attribute.rb +67 -0
  6. data/lib/active_support/core_ext/enumerable.rb +1 -1
  7. data/lib/active_support/core_ext/kernel/singleton_class.rb +13 -0
  8. data/lib/active_support/core_ext/module/remove_method.rb +6 -0
  9. data/lib/active_support/core_ext/object/misc.rb +3 -0
  10. data/lib/active_support/core_ext/range/blockless_step.rb +1 -1
  11. data/lib/active_support/core_ext/string/output_safety.rb +0 -11
  12. data/lib/active_support/dependencies.rb +36 -12
  13. data/lib/active_support/deprecation.rb +7 -0
  14. data/lib/active_support/json/backends/yajl.rb +1 -1
  15. data/lib/active_support/ordered_hash.rb +6 -0
  16. data/lib/active_support/testing/performance.rb +1 -1
  17. data/lib/active_support/values/time_zone.rb +5 -1
  18. data/lib/active_support/vendor.rb +2 -2
  19. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n.rb +92 -105
  20. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend.rb +5 -4
  21. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/active_record.rb +61 -0
  22. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/active_record/missing.rb +4 -6
  23. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/active_record/store_procs.rb +0 -0
  24. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/active_record/translation.rb +8 -3
  25. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/base.rb +55 -84
  26. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/cache.rb +1 -0
  27. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/cascade.rb +0 -1
  28. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/chain.rb +3 -1
  29. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/cldr.rb +0 -0
  30. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/fallbacks.rb +0 -0
  31. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/flatten.rb +113 -0
  32. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/gettext.rb +0 -0
  33. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/interpolation_compiler.rb +8 -4
  34. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/key_value.rb +102 -0
  35. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/memoize.rb +48 -0
  36. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/metadata.rb +5 -13
  37. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/backend/pluralization.rb +0 -0
  38. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/simple.rb +87 -0
  39. data/lib/active_support/vendor/i18n-0.4.1/i18n/backend/transliterator.rb +98 -0
  40. data/lib/active_support/vendor/i18n-0.4.1/i18n/config.rb +84 -0
  41. data/lib/active_support/vendor/i18n-0.4.1/i18n/core_ext/hash.rb +29 -0
  42. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/core_ext/string/interpolate.rb +3 -4
  43. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/exceptions.rb +0 -0
  44. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/gettext.rb +2 -0
  45. data/lib/active_support/vendor/{i18n-0.3.7/i18n/helpers/gettext.rb → i18n-0.4.1/i18n/gettext/helpers.rb} +2 -2
  46. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/gettext/po_parser.rb +0 -0
  47. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/locale.rb +0 -0
  48. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/locale/fallbacks.rb +0 -0
  49. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/locale/tag.rb +0 -0
  50. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/locale/tag/parents.rb +0 -0
  51. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/locale/tag/rfc4646.rb +0 -0
  52. data/lib/active_support/vendor/{i18n-0.3.7 → i18n-0.4.1}/i18n/locale/tag/simple.rb +0 -0
  53. data/lib/active_support/vendor/i18n-0.4.1/i18n/version.rb +3 -0
  54. data/lib/active_support/version.rb +1 -1
  55. data/lib/active_support/whiny_nil.rb +1 -1
  56. metadata +48 -43
  57. data/lib/active_support/vendor/i18n-0.3.7/i18n/backend/active_record.rb +0 -66
  58. data/lib/active_support/vendor/i18n-0.3.7/i18n/backend/fast.rb +0 -69
  59. data/lib/active_support/vendor/i18n-0.3.7/i18n/backend/helpers.rb +0 -68
  60. data/lib/active_support/vendor/i18n-0.3.7/i18n/backend/links.rb +0 -34
  61. data/lib/active_support/vendor/i18n-0.3.7/i18n/backend/simple.rb +0 -22
  62. data/lib/active_support/vendor/i18n-0.3.7/i18n/core_ext/hash/except.rb +0 -8
  63. data/lib/active_support/vendor/i18n-0.3.7/i18n/core_ext/hash/slice.rb +0 -8
  64. data/lib/active_support/vendor/i18n-0.3.7/i18n/core_ext/object/meta_class.rb +0 -5
  65. data/lib/active_support/vendor/i18n-0.3.7/i18n/helpers.rb +0 -5
  66. data/lib/active_support/vendor/i18n-0.3.7/i18n/version.rb +0 -3
data/CHANGELOG CHANGED
@@ -1,3 +1,14 @@
1
+ *2.3.9 (August 29, 2010)*
2
+
3
+ * i18n: bundle i18n 0.4.1 for forward compatibility with Rails 3. Deprecates {{foo}} interpolation syntax in favor of 1.9-native %{foo}.
4
+
5
+ * Deprecate Kernel#returning in favor of Object#tap since it's included in Ruby 1.8.7 and later. [Santiago Pastorino]
6
+
7
+ * Deprecates ActiveSupport::Dependencies.load_(once_)paths, renamed to autoload_(once_)paths. [fxn]
8
+
9
+ * Deprecates Array#random_element, renamed to sample to match Ruby 1.9, thanks to Marc-Andre Lafortune. [fxn]
10
+
11
+
1
12
  *2.3.8 (May 24, 2010)*
2
13
 
3
14
  * Version bump.
@@ -33,7 +33,7 @@ module ActiveSupport #:nodoc:
33
33
  if block_given?
34
34
  collection.each_slice(number) { |slice| yield(slice) }
35
35
  else
36
- returning [] do |groups|
36
+ [].tap do |groups|
37
37
  collection.each_slice(number) { |group| groups << group }
38
38
  end
39
39
  end
@@ -8,14 +8,34 @@ module ActiveSupport #:nodoc:
8
8
  # https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/4555
9
9
  #
10
10
  def rand # :nodoc:
11
- ActiveSupport::Deprecation.warn 'Array#rand is deprecated and will be removed in Rails 3. Use "random_element" instead', caller
12
- random_element
11
+ ActiveSupport::Deprecation.warn 'Array#rand is deprecated and will be removed in Rails 3. Use Array#sample instead', caller
12
+ sample
13
13
  end
14
14
 
15
15
  # Returns a random element from the array.
16
- def random_element
17
- self[Kernel.rand(length)]
16
+ def random_element # :nodoc:
17
+ ActiveSupport::Deprecation.warn 'Array#random_element is deprecated and will be removed in Rails 3. Use Array#sample instead', caller
18
+ sample
18
19
  end
20
+
21
+ # Backport of Array#sample based on Marc-Andre Lafortune's http://github.com/marcandre/backports/
22
+ def sample(n=nil)
23
+ return self[Kernel.rand(size)] if n.nil?
24
+ n = n.to_int
25
+ rescue Exception => e
26
+ raise TypeError, "Coercion error: #{n.inspect}.to_int => Integer failed:\n(#{e.message})"
27
+ else
28
+ raise TypeError, "Coercion error: #{n}.to_int did NOT return an Integer (was #{n.class})" unless n.kind_of? ::Integer
29
+ raise ArgumentError, "negative array size" if n < 0
30
+ n = size if n > size
31
+ result = ::Array.new(self)
32
+ n.times do |i|
33
+ r = i + Kernel.rand(size - i)
34
+ result[i], result[r] = result[r], result[i]
35
+ end
36
+ result[n..size] = []
37
+ result
38
+ end unless method_defined? :sample
19
39
  end
20
40
  end
21
41
  end
@@ -2,3 +2,4 @@ require 'active_support/core_ext/class/attribute_accessors'
2
2
  require 'active_support/core_ext/class/inheritable_attributes'
3
3
  require 'active_support/core_ext/class/removal'
4
4
  require 'active_support/core_ext/class/delegating_attributes'
5
+ require 'active_support/core_ext/class/attribute'
@@ -0,0 +1,67 @@
1
+ require 'active_support/core_ext/kernel/singleton_class'
2
+ require 'active_support/core_ext/module/remove_method'
3
+
4
+ class Class
5
+ # Declare a class-level attribute whose value is inheritable and
6
+ # overwritable by subclasses:
7
+ #
8
+ # class Base
9
+ # class_attribute :setting
10
+ # end
11
+ #
12
+ # class Subclass < Base
13
+ # end
14
+ #
15
+ # Base.setting = true
16
+ # Subclass.setting # => true
17
+ # Subclass.setting = false
18
+ # Subclass.setting # => false
19
+ # Base.setting # => true
20
+ #
21
+ # This matches normal Ruby method inheritance: think of writing an attribute
22
+ # on a subclass as overriding the reader method.
23
+ #
24
+ # For convenience, a query method is defined as well:
25
+ #
26
+ # Subclass.setting? # => false
27
+ #
28
+ # Instances may overwrite the class value in the same way:
29
+ #
30
+ # Base.setting = true
31
+ # object = Base.new
32
+ # object.setting # => true
33
+ # object.setting = false
34
+ # object.setting # => false
35
+ # Base.setting # => true
36
+ #
37
+ # To opt out of the instance writer method, pass :instance_writer => false.
38
+ #
39
+ # object.setting = false # => NoMethodError
40
+ def class_attribute(*attrs)
41
+ instance_writer = !attrs.last.is_a?(Hash) || attrs.pop[:instance_writer]
42
+
43
+ attrs.each do |name|
44
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
45
+ def self.#{name}() nil end
46
+ def self.#{name}?() !!#{name} end
47
+
48
+ def self.#{name}=(val)
49
+ singleton_class.class_eval do
50
+ remove_possible_method(:#{name})
51
+ define_method(:#{name}) { val }
52
+ end
53
+ end
54
+
55
+ def #{name}
56
+ defined?(@#{name}) ? @#{name} : singleton_class.#{name}
57
+ end
58
+
59
+ def #{name}?
60
+ !!#{name}
61
+ end
62
+ RUBY
63
+
64
+ attr_writer name if instance_writer
65
+ end
66
+ end
67
+ end
@@ -75,7 +75,7 @@ module Enumerable
75
75
  # (1..5).each_with_object(1) { |value, memo| memo *= value } # => 1
76
76
  #
77
77
  def each_with_object(memo, &block)
78
- returning memo do |m|
78
+ memo.tap do |m|
79
79
  each do |element|
80
80
  block.call(element, m)
81
81
  end
@@ -0,0 +1,13 @@
1
+ module Kernel
2
+ # Returns the object's singleton class.
3
+ def singleton_class
4
+ class << self
5
+ self
6
+ end
7
+ end unless respond_to?(:singleton_class) # exists in 1.9.2
8
+
9
+ # class_eval on an object acts like singleton_class.class_eval.
10
+ def class_eval(*args, &block)
11
+ singleton_class.class_eval(*args, &block)
12
+ end
13
+ end
@@ -0,0 +1,6 @@
1
+ class Module
2
+ def remove_possible_method(method)
3
+ remove_method(method)
4
+ rescue NameError
5
+ end
6
+ end
@@ -1,3 +1,5 @@
1
+ require 'active_support/deprecation'
2
+
1
3
  class Object
2
4
  # Returns +value+ after yielding +value+ to the block. This simplifies the
3
5
  # process of constructing an object, performing work on the object, and then
@@ -36,6 +38,7 @@ class Object
36
38
  #
37
39
  # foo # => ['bar', 'baz']
38
40
  def returning(value)
41
+ ActiveSupport::Deprecation.warn('Object#returning has been deprecated in favor of Object#tap.', caller)
39
42
  yield(value)
40
43
  value
41
44
  end
@@ -12,7 +12,7 @@ module ActiveSupport #:nodoc:
12
12
  if block_given?
13
13
  step_without_blockless(value, &block)
14
14
  else
15
- returning [] do |array|
15
+ [].tap do |array|
16
16
  step_without_blockless(value) { |step| array << step }
17
17
  end
18
18
  end
@@ -62,17 +62,6 @@ end
62
62
 
63
63
  module ActiveSupport #:nodoc:
64
64
  class SafeBuffer < String
65
- alias safe_concat concat
66
-
67
- def concat(value)
68
- if value.html_safe?
69
- super(value)
70
- else
71
- super(ERB::Util.h(value))
72
- end
73
- end
74
- alias << concat
75
-
76
65
  def +(other)
77
66
  dup.concat(other)
78
67
  end
@@ -20,14 +20,38 @@ module ActiveSupport #:nodoc:
20
20
 
21
21
  # The set of directories from which we may automatically load files. Files
22
22
  # under these directories will be reloaded on each request in development mode,
23
- # unless the directory also appears in load_once_paths.
24
- mattr_accessor :load_paths
25
- self.load_paths = []
23
+ # unless the directory also appears in autoload_once_paths.
24
+ mattr_accessor :autoload_paths
25
+ self.autoload_paths = []
26
+
27
+ # Deprecated, use autoload_paths.
28
+ def self.load_paths
29
+ ActiveSupport::Deprecation.warn("ActiveSupport::Dependencies.load_paths is deprecated, please use autoload_paths instead", caller)
30
+ autoload_paths
31
+ end
32
+
33
+ # Deprecated, use autoload_paths=.
34
+ def self.load_paths=(paths)
35
+ ActiveSupport::Deprecation.warn("ActiveSupport::Dependencies.load_paths= is deprecated, please use autoload_paths= instead", caller)
36
+ self.autoload_paths = paths
37
+ end
26
38
 
27
39
  # The set of directories from which automatically loaded constants are loaded
28
- # only once. All directories in this set must also be present in +load_paths+.
29
- mattr_accessor :load_once_paths
30
- self.load_once_paths = []
40
+ # only once. All directories in this set must also be present in +autoload_paths+.
41
+ mattr_accessor :autoload_once_paths
42
+ self.autoload_once_paths = []
43
+
44
+ # Deprecated, use autoload_once_paths.
45
+ def self.load_once_paths
46
+ ActiveSupport::Deprecation.warn("ActiveSupport::Dependencies.load_once_paths is deprecated and removed in Rails 3, please use autoload_once_paths instead", caller)
47
+ autoload_once_paths
48
+ end
49
+
50
+ # Deprecated, use autoload_once_paths=.
51
+ def self.load_once_paths=(paths)
52
+ ActiveSupport::Deprecation.warn("ActiveSupport::Dependencies.load_once_paths= is deprecated and removed in Rails 3, please use autoload_once_paths= instead", caller)
53
+ self.autoload_once_paths = paths
54
+ end
31
55
 
32
56
  # An array of qualified constant names that have been loaded. Adding a name to
33
57
  # this array will cause it to be unloaded the next time Dependencies are cleared.
@@ -305,7 +329,7 @@ module ActiveSupport #:nodoc:
305
329
 
306
330
  # Given +path+, a filesystem path to a ruby file, return an array of constant
307
331
  # paths which would cause Dependencies to attempt to load this file.
308
- def loadable_constants_for_path(path, bases = load_paths)
332
+ def loadable_constants_for_path(path, bases = autoload_paths)
309
333
  path = $1 if path =~ /\A(.*)\.rb\Z/
310
334
  expanded_path = File.expand_path(path)
311
335
 
@@ -326,10 +350,10 @@ module ActiveSupport #:nodoc:
326
350
  end.flatten.compact.uniq
327
351
  end
328
352
 
329
- # Search for a file in load_paths matching the provided suffix.
353
+ # Search for a file in autoload_paths matching the provided suffix.
330
354
  def search_for_file(path_suffix)
331
355
  path_suffix = path_suffix + '.rb' unless path_suffix.ends_with? '.rb'
332
- load_paths.each do |root|
356
+ autoload_paths.each do |root|
333
357
  path = File.join(root, path_suffix)
334
358
  return path if File.file? path
335
359
  end
@@ -339,14 +363,14 @@ module ActiveSupport #:nodoc:
339
363
  # Does the provided path_suffix correspond to an autoloadable module?
340
364
  # Instead of returning a boolean, the autoload base for this module is returned.
341
365
  def autoloadable_module?(path_suffix)
342
- load_paths.each do |load_path|
366
+ autoload_paths.each do |load_path|
343
367
  return load_path if File.directory? File.join(load_path, path_suffix)
344
368
  end
345
369
  nil
346
370
  end
347
371
 
348
372
  def load_once_path?(path)
349
- load_once_paths.any? { |base| path.starts_with? base }
373
+ autoload_once_paths.any? { |base| path.starts_with? base }
350
374
  end
351
375
 
352
376
  # Attempt to autoload the provided module name by searching for a directory
@@ -358,7 +382,7 @@ module ActiveSupport #:nodoc:
358
382
  return nil unless base_path = autoloadable_module?(path_suffix)
359
383
  mod = Module.new
360
384
  into.const_set const_name, mod
361
- autoloaded_constants << qualified_name unless load_once_paths.include?(base_path)
385
+ autoloaded_constants << qualified_name unless autoload_once_paths.include?(base_path)
362
386
  return mod
363
387
  end
364
388
 
@@ -120,6 +120,13 @@ module ActiveSupport
120
120
  end
121
121
 
122
122
  class DeprecationProxy #:nodoc:
123
+ def self.new(*args, &block)
124
+ object = args.first
125
+
126
+ return object unless object
127
+ super
128
+ end
129
+
123
130
  silence_warnings do
124
131
  instance_methods.each { |m| undef_method m unless m =~ /^__/ }
125
132
  end
@@ -1,4 +1,4 @@
1
- require 'yajl-ruby' unless defined?(Yajl)
1
+ require 'yajl' unless defined?(Yajl)
2
2
 
3
3
  module ActiveSupport
4
4
  module JSON
@@ -134,6 +134,8 @@ module ActiveSupport
134
134
  self
135
135
  end
136
136
 
137
+ alias_method :update, :merge!
138
+
137
139
  def merge(other_hash)
138
140
  dup.merge!(other_hash)
139
141
  end
@@ -145,6 +147,10 @@ module ActiveSupport
145
147
  self
146
148
  end
147
149
 
150
+ def invert
151
+ OrderedHash[self.to_a.map!{|key_value_pair| key_value_pair.reverse}]
152
+ end
153
+
148
154
  def inspect
149
155
  "#<OrderedHash #{super}>"
150
156
  end
@@ -24,7 +24,7 @@ module ActiveSupport
24
24
  end.freeze
25
25
 
26
26
  def self.included(base)
27
- base.superclass_delegating_accessor :profile_options
27
+ base.class_attribute :profile_options
28
28
  base.profile_options = DEFAULTS
29
29
  end
30
30
 
@@ -387,7 +387,11 @@ module ActiveSupport
387
387
  def [](arg)
388
388
  case arg
389
389
  when String
390
- zones_map[arg] ||= lookup(arg)
390
+ if tz = zones_map[arg]
391
+ tz
392
+ elsif tz = lookup(arg)
393
+ zones_map[arg] = tz
394
+ end
391
395
  when Numeric, ActiveSupport::Duration
392
396
  arg *= 3600 if arg.abs <= 13
393
397
  all.find { |z| z.utc_offset == arg.to_i }
@@ -21,9 +21,9 @@ rescue Gem::LoadError
21
21
  end
22
22
 
23
23
  begin
24
- gem 'i18n', '>= 0.3.3'
24
+ gem 'i18n', '>= 0.4.1'
25
25
  rescue Gem::LoadError
26
- $:.unshift "#{File.dirname(__FILE__)}/vendor/i18n-0.3.7"
26
+ $:.unshift "#{File.dirname(__FILE__)}/vendor/i18n-0.4.1"
27
27
  end
28
28
  require 'i18n'
29
29
 
@@ -12,94 +12,11 @@ require 'i18n/core_ext/string/interpolate'
12
12
 
13
13
  module I18n
14
14
  autoload :Backend, 'i18n/backend'
15
- autoload :Helpers, 'i18n/helpers'
15
+ autoload :Config, 'i18n/config'
16
+ autoload :Gettext, 'i18n/gettext'
16
17
  autoload :Locale, 'i18n/locale'
17
18
 
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
29
-
30
- # Returns the current backend. Defaults to +Backend::Simple+.
31
- def backend
32
- @@backend ||= Backend::Simple.new
33
- end
34
-
35
- # Sets the current backend. Used to set a custom backend.
36
- def backend=(backend)
37
- @@backend = backend
38
- end
39
-
40
- # Returns the current default locale. Defaults to :'en'
41
- def default_locale
42
- @@default_locale ||= :en
43
- end
44
-
45
- # Sets the current default locale. Used to set a custom default locale.
46
- def default_locale=(locale)
47
- @@default_locale = locale.to_sym rescue nil
48
- end
49
-
50
- # Returns an array of locales for which translations are available.
51
- # Unless you explicitely set the these through I18n.available_locales=
52
- # the call will be delegated to the backend and memoized on the I18n module.
53
- def available_locales
54
- @@available_locales ||= backend.available_locales
55
- end
56
-
57
- # Sets the available locales.
58
- def available_locales=(locales)
59
- @@available_locales = locales
60
- end
61
-
62
- # Returns the current default scope separator. Defaults to '.'
63
- def default_separator
64
- @@default_separator ||= '.'
65
- end
66
-
67
- # Sets the current default scope separator.
68
- def default_separator=(separator)
69
- @@default_separator = separator
70
- end
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
- # Sets the exception handler.
78
- def exception_handler=(exception_handler)
79
- @@exception_handler = exception_handler
80
- end
81
-
82
- # Allow clients to register paths providing translation data sources. The
83
- # backend defines acceptable sources.
84
- #
85
- # E.g. the provided SimpleBackend accepts a list of paths to translation
86
- # files which are either named *.rb and contain plain Ruby Hashes or are
87
- # named *.yml and contain YAML data. So for the SimpleBackend clients may
88
- # register translation files like this:
89
- # I18n.load_path << 'path/to/locale/en.yml'
90
- def load_path
91
- @@load_path ||= []
92
- end
93
-
94
- # Sets the load path instance. Custom implementations are expected to
95
- # behave like a Ruby Array.
96
- def load_path=(load_path)
97
- @@load_path = load_path
98
- end
99
- end
100
-
101
19
  class << self
102
-
103
20
  # Gets I18n configuration object.
104
21
  def config
105
22
  Thread.current[:i18n_config] ||= I18n::Config.new
@@ -163,7 +80,7 @@ module I18n
163
80
  # values passed to #translate as part of the options hash, with the keys matching
164
81
  # the interpolation variable names.
165
82
  #
166
- # <em>E.g.</em>, with a translation <tt>:foo => "foo {{bar}}"</tt> the option
83
+ # <em>E.g.</em>, with a translation <tt>:foo => "foo %{bar}"</tt> the option
167
84
  # value for the key +bar+ will be interpolated into the translation:
168
85
  # I18n.t :foo, :bar => 'baz' # => 'foo baz'
169
86
  #
@@ -184,7 +101,7 @@ module I18n
184
101
  #
185
102
  # The <tt>:count</tt> option can be used both for pluralization and interpolation.
186
103
  # <em>E.g.</em>, with the translation
187
- # <tt>:foo => ['{{count}} foo', '{{count}} foos']</tt>, count will
104
+ # <tt>:foo => ['%{count} foo', '%{count} foos']</tt>, count will
188
105
  # be interpolated to the pluralized translation:
189
106
  # I18n.t :foo, :count => 1 # => '1 foo'
190
107
  #
@@ -218,7 +135,7 @@ module I18n
218
135
  # called and passed the key and options.
219
136
  #
220
137
  # E.g. assuming the key <tt>:salutation</tt> resolves to:
221
- # lambda { |key, options| options[:gender] == 'm' ? "Mr. {{options[:name]}}" : "Mrs. {{options[:name]}}" }
138
+ # lambda { |key, options| options[:gender] == 'm' ? "Mr. %{options[:name]}" : "Mrs. %{options[:name]}" }
222
139
  #
223
140
  # Then <tt>I18n.t(:salutation, :gender => 'w', :name => 'Smith') will result in "Mrs. Smith".
224
141
  #
@@ -244,6 +161,69 @@ module I18n
244
161
  end
245
162
  alias :t! :translate!
246
163
 
164
+ # Transliterates UTF-8 characters to ASCII. By default this method will
165
+ # transliterate only Latin strings to an ASCII approximation:
166
+ #
167
+ # I18n.transliterate("Ærøskøbing")
168
+ # # => "AEroskobing"
169
+ #
170
+ # I18n.transliterate("日本語")
171
+ # # => "???"
172
+ #
173
+ # It's also possible to add support for per-locale transliterations. I18n
174
+ # expects transliteration rules to be stored at
175
+ # <tt>i18n.transliterate.rule</tt>.
176
+ #
177
+ # Transliteration rules can either be a Hash or a Proc. Procs must accept a
178
+ # single string argument. Hash rules inherit the default transliteration
179
+ # rules, while Procs do not.
180
+ #
181
+ # *Examples*
182
+ #
183
+ # Setting a Hash in <locale>.yml:
184
+ #
185
+ # i18n:
186
+ # transliterate:
187
+ # rule:
188
+ # ü: "ue"
189
+ # ö: "oe"
190
+ #
191
+ # Setting a Hash using Ruby:
192
+ #
193
+ # store_translations(:de, :i18n => {
194
+ # :transliterate => {
195
+ # :rule => {
196
+ # "ü" => "ue",
197
+ # "ö" => "oe"
198
+ # }
199
+ # }
200
+ # )
201
+ #
202
+ # Setting a Proc:
203
+ #
204
+ # translit = lambda {|string| MyTransliterator.transliterate(string) }
205
+ # store_translations(:xx, :i18n => {:transliterate => {:rule => translit})
206
+ #
207
+ # Transliterating strings:
208
+ #
209
+ # I18n.locale = :en
210
+ # I18n.transliterate("Jürgen") # => "Jurgen"
211
+ # I18n.locale = :de
212
+ # I18n.transliterate("Jürgen") # => "Juergen"
213
+ # I18n.transliterate("Jürgen", :locale => :en) # => "Jurgen"
214
+ # I18n.transliterate("Jürgen", :locale => :de) # => "Juergen"
215
+ def transliterate(*args)
216
+ options = args.pop if args.last.is_a?(Hash)
217
+ key = args.shift
218
+ locale = options && options.delete(:locale) || config.locale
219
+ raises = options && options.delete(:raise)
220
+ replacement = options && options.delete(:replacement)
221
+ config.backend.transliterate(locale, key, replacement)
222
+ rescue I18n::ArgumentError => exception
223
+ raise exception if raises
224
+ handle_exception(exception, locale, key, options)
225
+ end
226
+
247
227
  # Localizes certain objects, such as dates and numbers to local formatting.
248
228
  def localize(object, options = {})
249
229
  locale = options.delete(:locale) || config.locale
@@ -252,14 +232,29 @@ module I18n
252
232
  end
253
233
  alias :l :localize
254
234
 
235
+ # Executes block with given I18n.locale set.
236
+ def with_locale(tmp_locale = nil)
237
+ if tmp_locale
238
+ current_locale = self.locale
239
+ self.locale = tmp_locale
240
+ end
241
+ yield
242
+ ensure
243
+ self.locale = current_locale if tmp_locale
244
+ end
245
+
246
+
255
247
  # Merges the given locale, key and scope into a single array of keys.
256
248
  # Splits keys that contain dots into multiple keys. Makes sure all
257
249
  # keys are Symbols.
258
250
  def normalize_keys(locale, key, scope, separator = nil)
259
251
  separator ||= I18n.default_separator
260
- normalize_key(locale, separator) +
261
- normalize_key(scope, separator) +
262
- normalize_key(key, separator)
252
+
253
+ keys = []
254
+ keys.concat normalize_key(locale, separator)
255
+ keys.concat normalize_key(scope, separator)
256
+ keys.concat normalize_key(key, separator)
257
+ keys
263
258
  end
264
259
 
265
260
  # making these private until Ruby 1.9.2 can send to protected methods again
@@ -308,28 +303,20 @@ module I18n
308
303
  end
309
304
 
310
305
  def normalize_key(key, separator)
311
- normalized_key_cache(separator)[key] ||=
306
+ normalized_key_cache[separator][key] ||=
312
307
  case key
313
308
  when Array
314
309
  key.map { |k| normalize_key(k, separator) }.flatten
315
- when nil
316
- []
317
310
  else
318
- key = key.to_s
319
- if key == ''
320
- []
321
- elsif key.include?(separator)
322
- keys = key.split(separator) - ['']
323
- keys.map { |k| k.to_sym }
324
- else
325
- [key.to_sym]
326
- end
311
+ keys = key.to_s.split(separator)
312
+ keys.delete('')
313
+ keys.map!{ |k| k.to_sym }
314
+ keys
327
315
  end
328
316
  end
329
317
 
330
- def normalized_key_cache(separator)
318
+ def normalized_key_cache
331
319
  @normalized_key_cache ||= Hash.new { |h,k| h[k] = {} }
332
- @normalized_key_cache[separator]
333
320
  end
334
321
  end
335
322
  end