i18n-inflector 2.5.1 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author:: Paweł Wilk (mailto:pw@gnu.org)
4
4
  # Copyright:: (c) 2011 by Paweł Wilk
5
- # License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:COPYING Ruby License}.
5
+ # License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:docs/COPYING Ruby License}.
6
6
  #
7
7
  # This file contains more intuitive version of Set.
8
8
 
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author:: Paweł Wilk (mailto:pw@gnu.org)
4
4
  # Copyright:: (c) 2011 by Paweł Wilk
5
- # License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:COPYING Ruby License}.
5
+ # License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:docs/COPYING Ruby License}.
6
6
  #
7
7
  # This file contains class that is used to keep
8
8
  # inflection data.
@@ -21,9 +21,9 @@ module I18n
21
21
  def initialize(locale=nil)
22
22
  @kinds = Hash.new(false)
23
23
  @tokens = Hash.new(DUMMY_TOKEN)
24
- @defaults = Hash.new
25
- @known_kinds = nil
26
24
  @lazy_tokens = LazyHashEnumerator.new(@tokens)
25
+ @lazy_kinds = LazyArrayEnumerator.new(@kinds)
26
+ @defaults = Hash.new
27
27
  @locale = locale
28
28
  end
29
29
 
@@ -75,7 +75,6 @@ module I18n
75
75
  @tokens[token][:kind] = kind.to_sym
76
76
  @tokens[token][:description] = description.to_s
77
77
  @kinds[kind] = true
78
- @known_kinds = nil
79
78
  end
80
79
 
81
80
  # Tests if the token is a true token.
@@ -157,94 +156,95 @@ module I18n
157
156
  kind.nil? ? true : o[:kind] == kind
158
157
  end
159
158
 
160
- # Reads all the true tokens (not aliases).
159
+ # Iterates through all the true tokens (not aliases).
161
160
  #
162
- # @return [Hash] the true tokens in a
163
- # form of Hash (<tt>token => description</tt>)
164
- # @overload get_true_tokens
161
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>token => description</tt>)
162
+ # @yield [token, description] optional block in which each token will be yielded
163
+ # @yieldparam [Symbol] token a token
164
+ # @yieldparam [String] description a description string for a token
165
+ # @yieldreturn [LazyHashEnumerator] the lazy enumerator
166
+ # @overload each_true_token
165
167
  # Reads all the true tokens (not aliases).
166
- # @return [Hash] the true tokens in a
167
- # form of Hash (<tt>token => description</tt>)
168
- # @overload get_true_tokens(kind)
168
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>token => description</tt>)
169
+ # @overload each_true_token(kind)
169
170
  # Reads all the true tokens (not aliases) of the given +kind+.
170
171
  # @param [Symbol] kind the identifier of a kind
171
- # @return [Hash] the true tokens in a
172
- # form of Hash (<tt>token => description</tt>)
173
- def get_true_tokens(kind=nil)
172
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>token => description</tt>)
173
+ def each_true_token(kind=nil, &block)
174
174
  t = @lazy_tokens
175
175
  t = t.select { |token,data| data[:kind] == kind } unless kind.nil?
176
176
  t.select { |token,data| data[:target].nil? }.
177
- map { |token,data| data[:description] }.
178
- to_h
177
+ map { |token,data| data[:description] }.each(&block)
179
178
  end
180
179
 
181
- # Reads all the aliases.
180
+ # Iterates through all the aliases.
182
181
  #
183
- # @return [Hash] the aliases in a
184
- # form of Hash (<tt>alias => target</tt>)
185
- # @overload get_aliases
182
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>alias => target</tt>)
183
+ # @yield [alias, target] optional block in which each alias will be yielded
184
+ # @yieldparam [Symbol] alias an alias
185
+ # @yieldparam [Symbol] target a name of the target token
186
+ # @yieldreturn [LazyHashEnumerator] the lazy enumerator
187
+ # @overload each_alias
186
188
  # Reads all the aliases.
187
- # @return [Hash] the aliases in a
188
- # form of Hash (<tt>alias => target</tt>)
189
- # @overload get_aliases(kind)
189
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>alias => target</tt>)
190
+ # @overload each_alias(kind)
190
191
  # Reads all the aliases of the given +kind+.
191
192
  # @param [Symbol] kind the identifier of a kind
192
- # @return [Hash] the aliases in a
193
- # form of Hash (<tt>alias => target</tt>)
194
- def get_aliases(kind=nil)
193
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>alias => target</tt>)
194
+ def each_alias(kind=nil, &block)
195
195
  t = @lazy_tokens
196
196
  t = t.select { |token,data| data[:kind] == kind } unless kind.nil?
197
197
  t.reject { |token,data| data[:target].nil? }.
198
- map { |token,data| data[:target] }.
199
- to_h
198
+ map { |token,data| data[:target] }.each(&block)
200
199
  end
201
200
 
202
- # Reads all the tokens in a way that it is possible to
201
+ # Iterates through all the tokens in a way that it is possible to
203
202
  # distinguish true tokens from aliases.
204
203
  #
205
204
  # @note True tokens have descriptions (String) and aliases
206
205
  # have targets (Symbol) assigned.
207
- # @return [Hash] the tokens in a
208
- # form of Hash (<tt>token => description|target</tt>)
209
- # @overload get_raw_tokens
206
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>token => description|target</tt>)
207
+ # @yield [token, value] optional block in which each token will be yielded
208
+ # @yieldparam [Symbol] token a token
209
+ # @yieldparam [Symbol, String] value a description string for a token or a target (if alias)
210
+ # @yieldreturn [LazyHashEnumerator] the lazy enumerator
211
+ # @overload each_raw_token
210
212
  # Reads all the tokens in a way that it is possible to
211
213
  # distinguish true tokens from aliases.
212
- # @return [Hash] the tokens in a
213
- # form of Hash (<tt>token => description|target</tt>)
214
- # @overload get_raw_tokens(kind)
214
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>token => description|target</tt>)
215
+ # @overload each_raw_token(kind)
215
216
  # Reads all the tokens of the given +kind+ in a way
216
217
  # that it is possible to distinguish true tokens from aliases.
217
218
  # @param [Symbol] kind the identifier of a kind
218
- # @return [Hash] the tokens in a
219
- # form of Hash (<tt>token => description|target</tt>)
220
- def get_raw_tokens(kind=nil)
219
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>token => description|target</tt>)
220
+ def each_raw_token(kind=nil, &block)
221
221
  t = @lazy_tokens
222
222
  t = t.select { |token,data| data[:kind] == kind } unless kind.nil?
223
223
  t.map { |token,data| data[:target] || data[:description] }.
224
- to_h
224
+ each(&block)
225
225
  end
226
226
 
227
- # Reads all the tokens (including aliases).
227
+ # Iterates through all the tokens (including aliases).
228
228
  #
229
- # @note Use {#get_raw_tokens} if you want to distinguish
229
+ # @note Use {#each_raw_token} if you want to distinguish
230
230
  # true tokens from aliases.
231
- # @return [Hash] the tokens in a
232
- # form of Hash (<tt>token => description</tt>)
233
- # @overload get_tokens
231
+ # @return return [LazyHashEnumerator] the lazy enumerator (<tt>token => description</tt>)
232
+ # @yield [token, description] optional block in which each token will be yielded
233
+ # @yieldparam [Symbol] token a token
234
+ # @yieldparam [String] description a description string for a token
235
+ # @yieldreturn [LazyHashEnumerator] the lazy enumerator
236
+ # @overload each_token
234
237
  # Reads all the tokens (including aliases).
235
- # @return [Hash] the tokens in a
236
- # form of Hash (<tt>token => description</tt>)
237
- # @overload get_tokens(kind)
238
+ # @return return [LazyHashEnumerator] the lazy enumerator (<tt>token => description</tt>)
239
+ # @overload each_token(kind)
238
240
  # Reads all the tokens (including aliases) of the
239
241
  # given +kind+.
240
242
  # @param [Symbol] kind the identifier of a kind
241
- # @return [Hash] the tokens in a
242
- # form of Hash (<tt>token => description</tt>)
243
- def get_tokens(kind=nil)
243
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>token => description</tt>)
244
+ def each_token(kind=nil, &block)
244
245
  t = @lazy_tokens
245
246
  t = t.select { |token,data| data[:kind] == kind } unless kind.nil?
246
- t.map { |token,data| data[:description] }.
247
- to_h
247
+ t.map { |token,data| data[:description] }.each(&block)
248
248
  end
249
249
 
250
250
  # Gets a target token for the alias.
@@ -317,13 +317,6 @@ module I18n
317
317
  k == kind ? r : nil
318
318
  end
319
319
 
320
- # Gets all known kinds.
321
- #
322
- # @return [Array<Symbol>] an array containing all the known kinds
323
- def get_kinds
324
- @known_kinds ||= @kinds.keys
325
- end
326
-
327
320
  # Reads the default token of a kind.
328
321
  #
329
322
  # @note It will always return true token (not an alias).
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author:: Paweł Wilk (mailto:pw@gnu.org)
4
4
  # Copyright:: (c) 2011 by Paweł Wilk
5
- # License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:COPYING Ruby License}.
5
+ # License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:docs/COPYING Ruby License}.
6
6
  #
7
7
  # This file contains class that is used to keep
8
8
  # inflection data for strict kinds.
@@ -26,15 +26,11 @@ module I18n
26
26
  # It makes chaining calls to internal data easier.
27
27
  DUMMY_TOKENS = Hash.new(DUMMY_TOKEN).freeze
28
28
 
29
- # This constant contains a dummy iterator for hash of hashes.
30
- # It makes chaining calls to internal data easier.
31
- DUMMY_T_LAZY = LazyHashEnumerator.new(DUMMY_TOKENS).freeze
32
-
33
29
  # This constant contains a dummy hash. It makes
34
30
  # chaining calls to internal data easier.
35
31
  DUMMY_HASH = Hash.new.freeze
36
32
 
37
- # Locale that this database works for.
33
+ # Locale this database works for.
38
34
  attr_reader :locale
39
35
 
40
36
  # Initializes internal structures.
@@ -43,9 +39,8 @@ module I18n
43
39
  # the object to be labeled with
44
40
  def initialize(locale=nil)
45
41
  @tokens = Hash.new(DUMMY_TOKENS)
46
- @lazy_tokens = Hash.new(DUMMY_T_LAZY)
42
+ @lazy_kinds = LazyArrayEnumerator.new(@tokens)
47
43
  @defaults = Hash.new
48
- @known_kinds = nil
49
44
  @locale = locale
50
45
  end
51
46
 
@@ -83,9 +78,7 @@ module I18n
83
78
  kind = kind.to_sym
84
79
  kind_tree = @tokens[kind]
85
80
  if kind_tree.equal?(DUMMY_TOKENS)
86
- @known_kinds = nil
87
81
  kind_tree = @tokens[kind] = Hash.new(DUMMY_TOKEN)
88
- @lazy_tokens[kind] = LazyHashEnumerator.new(kind_tree)
89
82
  end
90
83
  token = kind_tree[token] = {}
91
84
  token[:description] = description.to_s
@@ -155,56 +148,70 @@ module I18n
155
148
  not @tokens[kind][alias_name][:target].nil?
156
149
  end
157
150
 
158
- # Reads all the true tokens (not aliases) of the
151
+ # Iterates through all the true tokens (not aliases) of the
159
152
  # given strict kind.
160
153
  #
161
154
  # @param [Symbol] kind the identifier of a kind
162
- # @return [Hash] the true tokens of the given kind in a
163
- # form of Hash (<tt>token => description</tt>)
164
- def get_true_tokens(kind)
165
- @lazy_tokens[kind].
166
- reject { |token,data| !data[:target].nil? }.
155
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>token => description</tt>)
156
+ # @yield [token, description] optional block in which each token will be yielded
157
+ # @yieldparam [Symbol] token a token
158
+ # @yieldparam [String] description a description string for a token
159
+ # @yieldreturn [LazyHashEnumerator] the lazy enumerator
160
+ def each_true_token(kind, &block)
161
+ LazyHashEnumerator.new(@tokens[kind]).
162
+ select { |token,data| data[:target].nil? }.
167
163
  map { |token,data| data[:description] }.
168
- to_h
164
+ each(&block)
169
165
  end
170
166
 
171
- # Reads all the aliases of the given strict kind.
167
+ # Iterates through all the aliases of the given strict kind.
172
168
  #
173
169
  # @param [Symbol] kind the identifier of a kind
174
- # @return [Hash] the aliases of the given kind in a
175
- # form of Hash (<tt>alias => target</tt>)
176
- def get_aliases(kind)
177
- @lazy_tokens[kind].
170
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>token => target</tt>)
171
+ # @yield [alias, target] optional block in which each alias will be yielded
172
+ # @yieldparam [Symbol] alias an alias
173
+ # @yieldparam [Symbol] target a name of the target token
174
+ # @yieldreturn [LazyHashEnumerator] the lazy enumerator
175
+ def each_alias(kind, &block)
176
+ LazyHashEnumerator.new(@tokens[kind]).
178
177
  reject { |token,data| data[:target].nil? }.
179
178
  map { |token,data| data[:target] }.
180
- to_h
179
+ each(&block)
181
180
  end
182
181
 
183
- # Reads all the tokens of the given strict kind
182
+ # Iterates through all the tokens of the given strict kind
184
183
  # in a way that it is possible to
185
184
  # distinguish true tokens from aliases.
186
185
  #
187
186
  # @note True tokens have descriptions (String) and aliases
188
187
  # have targets (Symbol) assigned.
189
188
  # @param [Symbol] kind the identifier of a kind
190
- # @return [Hash] the tokens of the given kind in a
191
- # form of Hash (<tt>token => description|target</tt>)
192
- def get_raw_tokens(kind)
193
- @lazy_tokens[kind].
189
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>token => description|target</tt>)
190
+ # @yield [token, value] optional block in which each token will be yielded
191
+ # @yieldparam [Symbol] token a token
192
+ # @yieldparam [Symbol, String] value a description string for a token or a target (if alias)
193
+ # @yieldreturn [LazyHashEnumerator] the lazy enumerator
194
+ def each_raw_token(kind, &block)
195
+ LazyHashEnumerator.new(@tokens[kind]).
194
196
  map { |token,data| data[:target] || data[:description] }.
195
- to_h
197
+ each(&block)
196
198
  end
197
199
 
198
- # Reads all the tokens (including aliases) of the given
200
+ # Iterates through all the tokens (including aliases) of the given
199
201
  # strict kind.
200
202
  #
201
- # @note Use {#get_raw_tokens} if you want to distinguish
203
+ # @note Use {#each_raw_token} if you want to distinguish
202
204
  # true tokens from aliases.
203
205
  # @param [Symbol] kind the identifier of a kind
204
- # @return [Hash] the tokens of the given kind in a
205
- # form of Hash (<tt>token => description</tt>)
206
- def get_tokens(kind)
207
- @lazy_tokens[kind].map{ |token,data| data[:description] }.to_h
206
+ # @return [LazyHashEnumerator] the lazy enumerator (<tt>token => description</tt>)
207
+ # @yield [token, description] optional block in which each token will be yielded
208
+ # @yieldparam [Symbol] token a token
209
+ # @yieldparam [String] description a description string for a token
210
+ # @yieldreturn [LazyHashEnumerator] the lazy enumerator
211
+ def each_token(kind, &block)
212
+ LazyHashEnumerator.new(@tokens[kind]).
213
+ map{ |token,data| data[:description] }.
214
+ each(&block)
208
215
  end
209
216
 
210
217
  # Gets a target token for the given alias of a strict kind.
@@ -249,12 +256,14 @@ module I18n
249
256
  o[:target].nil? ? token : o[:target]
250
257
  end
251
258
 
252
- # Gets all known strict kinds.
259
+ # Iterates through all known strict kinds.
253
260
  #
254
- # @return [Array<Symbol>] an array containing all the known strict
255
- # kinds
256
- def get_kinds
257
- @known_kinds ||= @tokens.keys
261
+ # @return [LazyArrayEnumerator] the lazy enumerator
262
+ # @yield [kind] optional block in which each kind will be yielded
263
+ # @yieldparam [Symbol] kind the inflection kind
264
+ # @yieldreturn [LazyArrayEnumerator] the lazy enumerator
265
+ def each_kind(&block)
266
+ @lazy_kinds.map{|k,v| k}.each(&block)
258
267
  end
259
268
 
260
269
  # Reads the default token of a strict kind.
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author:: Paweł Wilk (mailto:pw@gnu.org)
4
4
  # Copyright:: (c) 2011 by Paweł Wilk
5
- # License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:COPYING Ruby License}.
5
+ # License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:docs/COPYING Ruby License}.
6
6
  #
7
7
  # This file contains a stub of I18n::Inflector module,
8
8
  # which extends I18n by adding the ability
@@ -22,7 +22,7 @@ module I18n
22
22
  end
23
23
  end
24
24
 
25
- # @version 2.5
25
+ # @version 2.6
26
26
  # @api public
27
27
  #
28
28
  # This module contains inflection classes and modules for enabling
@@ -32,7 +32,7 @@ module I18n
32
32
  # so it will interpolate additional inflection data present
33
33
  # in translations.
34
34
  #
35
- # @see file:USAGE
35
+ # @see file:docs/USAGE
36
36
  module Inflector
37
37
 
38
38
  end # module Inflector
@@ -2,7 +2,7 @@
2
2
  #
3
3
  # Author:: Paweł Wilk (mailto:pw@gnu.org)
4
4
  # Copyright:: (c) 2011 by Paweł Wilk
5
- # License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:COPYING Ruby License}.
5
+ # License:: This program is licensed under the terms of {file:docs/LGPL GNU Lesser General Public License} or {file:docs/COPYING Ruby License}.
6
6
  #
7
7
  # This file contains I18n::Inflector::Interpolate module,
8
8
  # which is included in the API.
@@ -44,6 +44,7 @@ module I18n
44
44
  # that overrides global setting (see: {I18n::Inflector::InflectionOptions#interpolate_symbols})
45
45
  # @return [String] the string with interpolated patterns
46
46
  def interpolate(string, locale, options = {})
47
+ @inflector_opt_cache = nil
47
48
 
48
49
  case string
49
50
 
@@ -96,18 +97,21 @@ module I18n
96
97
  suff = key.delete(:@suffix).to_s
97
98
  kind = key.delete(:@kind).to_s
98
99
  free = key.delete(:@free)
99
- free = free.nil? ? "" : (Operators::Tokens::OR + free.to_s)
100
+ free = free.nil? ? "" : ("" << Operators::Tokens::OR << free.to_s)
100
101
 
101
- pref + Markers::PATTERN + kind + Markers::PATTERN_BEGIN +
102
- key.map { |k,v| k.to_s + Operators::Tokens::ASSIGN + v.to_s }.
103
- join(Operators::Tokens::OR) + free + Markers::PATTERN_END + suff
102
+ "" << pref << Markers::PATTERN << kind << Markers::PATTERN_BEGIN <<
103
+ key.map { |k,v| "" << k.to_s << Operators::Tokens::ASSIGN << v.to_s }.
104
+ join(Operators::Tokens::OR) << free << Markers::PATTERN_END << suff
104
105
  end
105
106
 
106
107
  private
107
108
 
108
109
  # @private
109
110
  def interpolate_core(string, locale, options)
110
- passed_kinds = options.except(*Reserved::KEYS)
111
+
112
+ @inflector_opt_cache ||= options.except(*Reserved::KEYS)
113
+ passed_kinds = @inflector_opt_cache
114
+
111
115
  raises = options[:inflector_raises]
112
116
  aliased_patterns = options[:inflector_aliased_patterns]
113
117
  unknown_defaults = options[:inflector_unknown_defaults]
@@ -117,11 +121,11 @@ module I18n
117
121
  idb_strict = @idb_strict[locale]
118
122
 
119
123
  string.gsub(PATTERN_REGEXP) do
120
- pattern_fix = $1
121
- strict_kind = $2
122
- pattern_content = $3
123
- multipattern = $4
124
- ext_pattern = $&
124
+ pattern_fix = $1 # character sticked to the left side of a pattern
125
+ strict_kind = $2 # strict kind(s) if any
126
+ pattern_content = $3 # content of a pattern
127
+ multipattern = $4 # another pattern(s) sticked to the right side of a pattern
128
+ ext_pattern = $& # the matching string
125
129
 
126
130
  # initialize some defaults
127
131
  ext_freetext = ''
@@ -141,11 +145,13 @@ module I18n
141
145
  patterns = []
142
146
  patterns << pattern_content
143
147
  patterns += multipattern.scan(MULTI_REGEXP).flatten
144
- next pattern_fix + patterns.map do |content|
145
- interpolate_core(Markers::PATTERN + strict_kind +
146
- Markers::PATTERN_BEGIN + content +
147
- Markers::PATTERN_END, locale, options)
148
- end.join
148
+ next "" << pattern_fix <<
149
+ patterns.map do |content|
150
+ interpolate_core("" << Markers::PATTERN << strict_kind <<
151
+ Markers::PATTERN_BEGIN << content <<
152
+ Markers::PATTERN_END,
153
+ locale, options)
154
+ end.join
149
155
  end
150
156
 
151
157
  # set parsed kind if strict kind is given (named pattern is parsed)
@@ -156,7 +162,7 @@ module I18n
156
162
  default_token = nil
157
163
  subdb = idb
158
164
  else
159
- sym_parsed_kind = (Markers::STRICT_KIND + strict_kind).to_sym
165
+ sym_parsed_kind = ("" << Markers::STRICT_KIND << strict_kind).to_sym
160
166
 
161
167
  if strict_kind.include?(Operators::Tokens::AND)
162
168
 
@@ -181,10 +187,10 @@ module I18n
181
187
  !idb_strict.has_kind?(strict_kind.to_sym))
182
188
  raise I18n::InvalidInflectionKind.new(locale, ext_pattern, sym_parsed_kind) if raises
183
189
  # Take a free text for invalid kind and return it
184
- next pattern_fix + pattern_content.scan(TOKENS_REGEXP).reverse.
185
- select { |t,v,f| t.nil? && !f.nil? }.
186
- map { |t,v,f| f.to_s }.
187
- first.to_s
190
+ next "" << pattern_fix << pattern_content.scan(TOKENS_REGEXP).reverse.
191
+ select { |t,v,f| t.nil? && !f.nil? }.
192
+ map { |t,v,f| f.to_s }.
193
+ first.to_s
188
194
  else
189
195
  strict_kind = strict_kind.to_sym
190
196
  parsed_kind = strict_kind
@@ -197,11 +203,12 @@ module I18n
197
203
 
198
204
  # process pattern content's
199
205
  pattern_content.scan(TOKENS_REGEXP) do
200
- ext_token = $1.to_s
201
- ext_value = $2.to_s
202
- ext_freetext = $3.to_s
206
+ ext_token = $1.to_s # token(s)
207
+ ext_value = $2.to_s # value of token(s)
208
+ ext_freetext = $3.to_s # freetext if any
209
+ ext_tokens = nil
203
210
  tokens = Hash.new(false)
204
- negatives = Hash.new(false)
211
+ negatives = Hash.new(false)
205
212
  kind = nil
206
213
  passed_token = nil
207
214
  result = nil
@@ -219,18 +226,20 @@ module I18n
219
226
 
220
227
  # unroll wildcard token
221
228
  if ext_token == Operators::Tokens::WILDCARD
222
-
223
229
  if parsed_kind.nil?
224
230
  # wildcard for a regular kind that we do not know yet
225
231
  wildcard_value = ext_value
226
232
  else
227
233
  # wildcard for a known strict or regular kind
228
- ext_token = subdb.get_true_tokens(parsed_kind).keys.join(Operators::Token::OR)
234
+ ext_tokens = subdb.each_true_token(parsed_kind).each_key.map{|k|k.to_s}
229
235
  end
230
236
  end
231
237
 
232
- # split tokens from group if comma is present and put into fast list
233
- ext_token.split(Operators::Token::OR).each do |t|
238
+ # split groupped tokens if comma is present and put into fast list
239
+ ext_tokens = ext_token.split(Operators::Token::OR) if ext_tokens.nil?
240
+
241
+ # for each token from group
242
+ ext_tokens.each do |t|
234
243
  # token name corrupted
235
244
  if t.to_s.empty?
236
245
  raise I18n::InvalidInflectionToken.new(locale, ext_pattern, t) if raises
@@ -306,20 +315,29 @@ module I18n
306
315
 
307
316
  # get passed token from options or from a default token
308
317
  if passed_kinds.has_key?(expected_kind)
318
+
309
319
  passed_token = passed_kinds[expected_kind]
320
+
310
321
  if passed_token.is_a?(Method)
322
+
311
323
  passed_token = passed_token.call { next expected_kind, locale }
312
- passed_kinds[expected_kind] = passed_token # cache the result
324
+ passed_kinds[expected_kind] = passed_token # cache the result
325
+
313
326
  elsif passed_token.is_a?(Proc)
327
+
314
328
  passed_token = passed_token.call(expected_kind, locale)
315
- passed_kinds[expected_kind] = passed_token # cache the result
329
+ passed_kinds[expected_kind] = passed_token # cache the result
330
+
316
331
  end
332
+
317
333
  orig_passed_token = passed_token
334
+
318
335
  # validate passed token's name
319
336
  if Reserved::Tokens.invalid?(passed_token, :OPTION)
320
337
  raise I18n::InvalidInflectionOption.new(locale, ext_pattern, orig_passed_token) if raises
321
338
  passed_token = default_token if unknown_defaults
322
339
  end
340
+
323
341
  else
324
342
  # current inflection option wasn't found
325
343
  # but delay this exception because we might use
@@ -432,7 +450,7 @@ module I18n
432
450
 
433
451
  end
434
452
 
435
- pattern_fix + (result || ext_freetext)
453
+ "" << pattern_fix << (result || ext_freetext)
436
454
 
437
455
  end # single pattern processing
438
456
 
@@ -469,13 +487,26 @@ module I18n
469
487
  results = tokens.split(Operators::Tokens::AND).map do |token|
470
488
  raise IndexError.new if token.empty?
471
489
  if value == Markers::LOUD_VALUE
472
- r = interpolate_core(Markers::PATTERN + kinds.next.to_s + Markers::PATTERN_BEGIN + token.to_s +
473
- Operators::Tokens::ASSIGN + value.to_s + Operators::Tokens::OR +
474
- Markers::PATTERN + Markers::PATTERN_END, locale, options)
490
+ r = interpolate_core("" << Markers::PATTERN <<
491
+ kinds.next.to_s <<
492
+ Markers::PATTERN_BEGIN <<
493
+ token.to_s <<
494
+ Operators::Tokens::ASSIGN <<
495
+ value.to_s <<
496
+ Operators::Tokens::OR <<
497
+ Markers::PATTERN <<
498
+ Markers::PATTERN_END,
499
+ locale, options)
475
500
  break if r == Markers::PATTERN # using this marker only as a helper to indicate empty result!
476
501
  else
477
- r = interpolate_core(Markers::PATTERN + kinds.next.to_s + Markers::PATTERN_BEGIN + token.to_s +
478
- Operators::Tokens::ASSIGN + value.to_s + Markers::PATTERN_END, locale, options)
502
+ r = interpolate_core("" << Markers::PATTERN <<
503
+ kinds.next.to_s <<
504
+ Markers::PATTERN_BEGIN <<
505
+ token.to_s <<
506
+ Operators::Tokens::ASSIGN <<
507
+ value.to_s <<
508
+ Markers::PATTERN_END,
509
+ locale, options)
479
510
  break if r != value # stop with this set, because something is not matching
480
511
  end
481
512
  r