public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
I18n: applied Luca Guidi's patch for better #interpolate performance

[#943 state:resolved]

Signed-off-by: Jeremy Kemper <jeremy@bitsweat.net>
svenfuchs (author)
Sat Aug 30 01:51:35 -0700 2008
jeremy (committer)
Sat Aug 30 02:02:33 -0700 2008
commit  be4ae1f5264d6593e9dec479af4503c4bde2877e
tree    bed414370deab12be649f29fb51724ccde8d3827
parent  efa6620a2a7b8ae7b42664ab81faef7df1368939
...
3
4
5
 
 
 
6
7
8
...
114
115
116
117
 
118
119
 
120
121
122
123
124
125
126
127
128
129
130
 
 
 
131
132
133
 
 
134
135
136
 
 
 
 
 
 
 
 
 
137
138
139
 
140
141
142
...
3
4
5
6
7
8
9
10
11
...
117
118
119
 
120
121
122
123
124
 
 
 
 
 
 
 
 
 
 
125
126
127
128
 
 
129
130
131
 
 
132
133
134
135
136
137
138
139
140
141
 
 
142
143
144
145
0
@@ -3,6 +3,9 @@ require 'strscan'
0
 module I18n
0
   module Backend
0
     class Simple
0
+      INTERPOLATION_RESERVED_KEYS = %w(scope default)
0
+      MATCH = /(\\\\)?\{\{([^\}]+)\}\}/
0
+
0
       # Accepts a list of paths to translation files. Loads translations from 
0
       # plain Ruby (*.rb) or YAML files (*.yml). See #load_rb and #load_yml
0
       # for details.
0
@@ -114,29 +117,29 @@ module I18n
0
         # the <tt>{{...}}</tt> key in a string (once for the string and once for the
0
         # interpolation).
0
         def interpolate(locale, string, values = {})
0
-          return string if !string.is_a?(String)
0
+          return string unless string.is_a?(String)
0
 
0
           string = string.gsub(/%d/, '{{count}}').gsub(/%s/, '{{value}}')
0
+
0
           if string.respond_to?(:force_encoding)
0
-             original_encoding = string.encoding
0
-             string.force_encoding(Encoding::BINARY)
0
-           end
0
-          s = StringScanner.new(string)
0
-          
0
-          while s.skip_until(/\{\{/)
0
-            s.string[s.pos - 3, 1] = '' and next if s.pre_match[-1, 1] == '\\'            
0
-            start_pos = s.pos - 2
0
-            key = s.scan_until(/\}\}/)[0..-3]
0
-            end_pos = s.pos - 1            
0
+            original_encoding = string.encoding
0
+            string.force_encoding(Encoding::BINARY)
0
+          end
0
 
0
-            raise ReservedInterpolationKey.new(key, string) if %w(scope default).include?(key)
0
-            raise MissingInterpolationArgument.new(key, string) unless values.has_key? key.to_sym
0
+          result = string.gsub(MATCH) do
0
+            escaped, pattern, key = $1, $2, $2.to_sym
0
 
0
-            s.string[start_pos..end_pos] = values[key.to_sym].to_s
0
-            s.unscan
0
+            if escaped
0
+              pattern
0
+            elsif INTERPOLATION_RESERVED_KEYS.include?(pattern)
0
+              raise ReservedInterpolationKey.new(pattern, string)
0
+            elsif !values.include?(key)
0
+              raise MissingInterpolationArgument.new(pattern, string)
0
+            else
0
+              values[key].to_s
0
+            end
0
           end
0
-          
0
-          result = s.string
0
+
0
           result.force_encoding(original_encoding) if original_encoding
0
           result
0
         end

Comments