GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Rubygem
Description: Merb Core: All you need. None you don't.
Homepage: http://www.merbivore.com
Clone URL: git://github.com/wycats/merb-core.git
jackdempsey's inflector improvements (backported from wycats' patch to 
Rails)
wycats (author)
Sun Jun 22 23:52:35 -0700 2008
commit  322cd6f8a98795c4dd9f613422b2287c96a9ab5f
tree    b34c56c938b669ee7a2da9a30dff16a1c7e0edf5
parent  78061ac6adbc56fedfefa683a79e8700aa2959f0
...
142
143
144
 
145
146
147
...
160
161
162
163
164
165
166
167
168
169
...
172
173
174
175
176
177
178
...
142
143
144
145
146
147
148
...
161
162
163
 
 
 
 
164
165
166
...
169
170
171
 
172
173
174
0
@@ -142,6 +142,7 @@ module English
0
     word 'sheep'
0
     word 'moose'
0
     word 'hovercraft'
0
+ word 'bass'
0
 
0
     # Two arguments defines a singular and plural exception.
0
 
0
@@ -160,10 +161,6 @@ module English
0
     word 'testis' , 'testes'
0
     word 'child' , 'children'
0
     word 'person' , 'people'
0
- word 'potato' , 'potatoes'
0
- word 'tomato' , 'tomatoes'
0
- word 'buffalo' , 'buffaloes'
0
- word 'torpedo' , 'torpedoes'
0
     word 'quiz' , 'quizes'
0
     word 'matrix' , 'matrices'
0
     word 'vertex' , 'vetices'
0
@@ -172,7 +169,6 @@ module English
0
     word 'mouse' , 'mice'
0
     word 'louse' , 'lice'
0
     word 'thesis' , 'theses'
0
- word 'thief' , 'thieves'
0
     word 'analysis' , 'analyses'
0
 
0
     # One-way singularization exception (convert plural to singular).
...
38
39
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
42
43
...
47
48
49
 
50
51
52
...
58
59
60
 
61
62
63
...
67
68
69
70
 
 
 
71
72
73
...
77
78
79
80
 
 
 
81
82
 
83
84
85
...
122
123
124
125
126
127
128
 
 
129
 
 
 
 
130
131
132
133
134
135
136
137
 
 
138
 
 
 
139
140
141
142
143
144
145
146
147
148
149
 
150
151
152
...
166
167
168
169
170
171
172
 
 
 
173
174
175
...
191
192
193
 
 
194
195
196
197
198
199
200
201
 
 
 
202
203
204
...
218
219
220
221
222
223
 
 
224
225
226
...
234
235
236
237
238
239
240
241
242
243
 
244
245
246
...
256
257
258
259
 
 
 
 
 
 
 
 
260
261
262
263
264
265
266
 
 
 
 
 
 
267
268
269
...
281
282
283
 
 
 
 
 
 
 
284
285
286
...
292
293
294
295
296
 
 
 
 
 
297
298
299
...
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
...
61
62
63
64
65
66
67
...
73
74
75
76
77
78
79
...
83
84
85
 
86
87
88
89
90
91
...
95
96
97
 
98
99
100
101
102
103
104
105
106
...
143
144
145
 
 
 
 
146
147
148
149
150
151
152
153
154
155
156
 
 
 
 
157
158
159
160
161
162
163
164
 
 
 
 
 
 
 
 
 
165
166
167
168
...
182
183
184
 
 
 
 
185
186
187
188
189
190
...
206
207
208
209
210
211
212
213
 
214
 
 
 
215
216
217
218
219
220
...
234
235
236
 
237
238
239
240
241
242
243
...
251
252
253
 
 
254
255
256
257
 
258
259
260
261
...
271
272
273
 
274
275
276
277
278
279
280
281
282
283
 
 
284
 
 
285
286
287
288
289
290
291
292
293
...
305
306
307
308
309
310
311
312
313
314
315
316
317
...
323
324
325
 
 
326
327
328
329
330
331
332
333
0
@@ -38,6 +38,20 @@ module English
0
         plural_word(singular, plural)
0
       end
0
 
1
+ def clear(type = :all)
0
+ if type == :singular || type == :all
0
+ @singular_of = {}
0
+ @singular_rules = []
0
+ @singularization_rules, @singularization_regex = nil, nil
0
+ end
0
+ if type == :plural || type == :all
0
+ @singular_of = {}
0
+ @singular_rules = []
0
+ @singularization_rules, @singularization_regex = nil, nil
0
+ end
0
+ end
0
+
0
+
0
       # Define a singularization exception.
0
       #
0
       # ==== Parameters
0
@@ -47,6 +61,7 @@ module English
0
       # plural form of the word
0
       def singular_word(singular, plural)
0
         @singular_of[plural] = singular
0
+ @singular_of[plural.capitalize] = singular.capitalize
0
       end
0
 
0
       # Define a pluralization exception.
0
@@ -58,6 +73,7 @@ module English
0
       # plural form of the word
0
       def plural_word(singular, plural)
0
         @plural_of[singular] = plural
0
+ @plural_of[singular.capitalize] = plural.capitalize
0
       end
0
 
0
       # Define a general rule.
0
@@ -67,7 +83,9 @@ module English
0
       # ending of the word in singular form
0
       # plural<String>::
0
       # ending of the word in plural form
0
- #
0
+ # whole_word<Boolean>::
0
+ # for capitalization, since words can be
0
+ # capitalized (Man => Men) #
0
       # ==== Examples
0
       # Once the following rule is defined:
0
       # Language::English::Inflector.rule 'y', 'ies'
0
@@ -77,9 +95,12 @@ module English
0
       # => flies
0
       # irb> "cry".plural
0
       # => cries
0
- def rule(singular, plural)
0
+ # Define a general rule.
0
+
0
+ def rule(singular, plural, whole_word = false)
0
         singular_rule(singular, plural)
0
         plural_rule(singular, plural)
0
+ word(singular, plural) if whole_word
0
       end
0
 
0
       # Define a singularization rule.
0
@@ -122,31 +143,26 @@ module English
0
 
0
       # Read prepared singularization rules.
0
       def singularization_rules
0
- return @singularization_rules if @singularization_rules
0
- sorted = @singular_rules.sort_by{ |s, p| "#{p}".size }.reverse
0
- @singularization_rules = sorted.collect do |s, p|
0
- [ /#{p}$/, "#{s}" ]
0
+ if defined?(@singularization_regex) && @singularization_regex
0
+ return [@singularization_regex, @singularization_hash]
0
         end
0
+ # No sorting needed: Regexen match on longest string
0
+ @singularization_regex = Regexp.new("(" + @singular_rules.map {|s,p| p}.join("|") + ")$", "i")
0
+ @singularization_hash = Hash[*@singular_rules.flatten].invert
0
+ [@singularization_regex, @singularization_hash]
0
       end
0
 
0
       # Read prepared pluralization rules.
0
       def pluralization_rules
0
- return @pluralization_rules if @pluralization_rules
0
- sorted = @plural_rules.sort_by{ |s, p| "#{s}".size }.reverse
0
- @pluralization_rules = sorted.collect do |s, p|
0
- [ /#{s}$/, "#{p}" ]
0
+ if defined?(@pluralization_regex) && @pluralization_regex
0
+ return [@pluralization_regex, @pluralization_hash]
0
         end
0
+ @pluralization_regex = Regexp.new("(" + @plural_rules.map {|s,p| s}.join("|") + ")$", "i")
0
+ @pluralization_hash = Hash[*@plural_rules.flatten]
0
+ [@pluralization_regex, @pluralization_hash]
0
       end
0
 
0
- #
0
- def plural_of
0
- @plural_of
0
- end
0
-
0
- #
0
- def singular_of
0
- @singular_of
0
- end
0
+ attr_reader :singular_of, :plural_of
0
 
0
       # Convert an English word from plurel to singular.
0
       #
0
@@ -166,10 +182,9 @@ module English
0
           return result.dup
0
         end
0
         result = word.dup
0
- return result if singular_of.value? result
0
- singularization_rules.each do |(match, replacement)|
0
- break if result.gsub!(match, replacement)
0
- end
0
+ regex, hash = singularization_rules
0
+ result.sub!(regex) {|m| hash[m]}
0
+ singular_of[word] = result
0
         return result
0
       end
0
 
0
@@ -191,14 +206,15 @@ module English
0
       # ==== Notes
0
       # Aliased as pluralize (a Railism)
0
       def plural(word)
0
+ # special exceptions
0
+ return "" if word == ""
0
         if result = plural_of[word]
0
           return result.dup
0
         end
0
- #return self.dup if /s$/ =~ self # ???
0
         result = word.dup
0
- pluralization_rules.each do |(match, replacement)|
0
- break if result.gsub!(match, replacement)
0
- end
0
+ regex, hash = pluralization_rules
0
+ result.sub!(regex) {|m| hash[m]}
0
+ plural_of[word] = result
0
         return result
0
       end
0
 
0
@@ -218,9 +234,10 @@ module English
0
     word 'moose'
0
     word 'hovercraft'
0
     word 'grass'
0
- word 'news'
0
     word 'rain'
0
     word 'milk'
0
+ word 'rice'
0
+ word 'plurals'
0
 
0
     # Two arguments defines a singular and plural exception.
0
 
0
@@ -234,13 +251,11 @@ module English
0
     word 'axis' , 'axes'
0
     word 'crisis' , 'crises'
0
     word 'testis' , 'testes'
0
- word 'child' , 'children'
0
- word 'person' , 'people'
0
     word 'potato' , 'potatoes'
0
     word 'tomato' , 'tomatoes'
0
     word 'buffalo' , 'buffaloes'
0
     word 'torpedo' , 'torpedoes'
0
- word 'quiz' , 'quizes'
0
+ word 'quiz' , 'quizzes'
0
     word 'matrix' , 'matrices'
0
     word 'vertex' , 'vertices'
0
     word 'index' , 'indices'
0
@@ -256,14 +271,23 @@ module English
0
     word 'thesaurus' , 'thesauri'
0
     word 'movie' , 'movies'
0
     word 'cactus' , 'cacti'
0
-
0
+ word 'plus' , 'plusses'
0
+ word 'cross' , 'crosses'
0
+ word 'medium' , 'media'
0
+ word 'cow' , 'kine'
0
+ word 'datum' , 'data'
0
+ word 'basis' , 'bases'
0
+ word 'diagnosis' , 'diagnoses'
0
+
0
     # One-way singularization exception (convert plural to singular).
0
 
0
- # singular_word 'cactus', 'cacti'
0
-
0
     # General rules.
0
-
0
- rule 'hive' , 'hives'
0
+ rule 'person' , 'people', true
0
+ rule 'shoe' , 'shoes', true
0
+ rule 'hive' , 'hives', true
0
+ rule 'man' , 'men', true
0
+ rule 'child' , 'children', true
0
+ rule 'news' , 'news', true
0
     rule 'rf' , 'rves'
0
     rule 'af' , 'aves'
0
     rule 'ero' , 'eroes'
0
@@ -281,6 +305,13 @@ module English
0
     rule 'y' , 'ies'
0
     rule 'x' , 'xes'
0
     rule 'lf' , 'lves'
0
+ rule 'ffe' , 'ffes'
0
+ rule 'afe' , 'aves'
0
+ rule 'ouse' , 'ouses'
0
+ # more cases of words ending in -oses not being singularized properly
0
+ # than cases of words ending in -osis
0
+# rule 'osis' , 'oses'
0
+ rule 'ox' , 'oxes'
0
     rule 'us' , 'uses'
0
     rule '' , 's'
0
 
0
@@ -292,8 +323,11 @@ module English
0
 
0
     # One-way plural rules.
0
 
0
- plural_rule 'fe' , 'ves' # safe, wife
0
- plural_rule 's' , 'ses'
0
+ #plural_rule 'fe' , 'ves' # safe, wife
0
+ plural_rule 's' , 'ses'
0
+ plural_rule 'ive' , 'ives' # don't want to snag wife
0
+ plural_rule 'fe' , 'ves' # don't want to snag perspectives
0
+
0
 
0
   end
0
 end
...
125
126
127
128
129
 
 
130
131
132
...
301
302
303
304
305
 
 
306
307
308
...
480
481
482
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
483
...
125
126
127
 
 
128
129
130
131
132
...
301
302
303
 
 
304
305
306
307
308
...
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
0
@@ -125,8 +125,8 @@ describe Language::English::Inflect, "#singular" do
0
     "torpedo".plural.should == "torpedoes"
0
   end
0
 
0
- it "pluralizes quiz => quizes" do
0
- "quiz".plural.should == "quizes"
0
+ it "pluralizes quiz => quizzes" do
0
+ "quiz".plural.should == "quizzes"
0
   end
0
 
0
   # used to be a bug exposed by this specs suite,
0
@@ -301,8 +301,8 @@ describe Language::English::Inflect, "#singular" do
0
     "shelf".plural.should == "shelves"
0
   end
0
 
0
- it "pluralizes plus => pluses" do
0
- "plus".plural.should == "pluses"
0
+ it "pluralizes plus => plusses" do
0
+ "plus".plural.should == "plusses"
0
   end
0
 
0
   it "pluralizes cat => cats" do
0
@@ -480,4 +480,85 @@ describe Language::English::Inflect, "#singular" do
0
   it "pluralizes spam => spams" do
0
     "spam".plural.should == "spams"
0
   end
0
+
0
+ it "pluralizes bus => buses" do
0
+ "bus".plural.should == "buses"
0
+ end
0
+
0
+ it "pluralizes rice => rice" do
0
+ "rice".plural.should == "rice"
0
+ end
0
+
0
+ # Some specs from Rails
0
+ SingularToPlural = {
0
+ "search" => "searches",
0
+ "switch" => "switches",
0
+ "fix" => "fixes",
0
+ "box" => "boxes",
0
+ "process" => "processes",
0
+ "address" => "addresses",
0
+ "case" => "cases",
0
+ "stack" => "stacks",
0
+ "wish" => "wishes",
0
+
0
+ "category" => "categories",
0
+ "query" => "queries",
0
+ "ability" => "abilities",
0
+ "agency" => "agencies",
0
+
0
+ "archive" => "archives",
0
+
0
+ "safe" => "saves",
0
+ "half" => "halves",
0
+
0
+ "move" => "moves",
0
+
0
+ "salesperson" => "salespeople",
0
+
0
+ "spokesman" => "spokesmen",
0
+
0
+ "basis" => "bases",
0
+ "diagnosis" => "diagnoses",
0
+ "diagnosis_a" => "diagnosis_as",
0
+
0
+ "datum" => "data",
0
+ "medium" => "media",
0
+
0
+ "node_child" => "node_children",
0
+
0
+ "experience" => "experiences",
0
+ "day" => "days",
0
+
0
+ "comment" => "comments",
0
+ "foobar" => "foobars",
0
+ "newsletter" => "newsletters",
0
+
0
+ "old_news" => "old_news",
0
+
0
+ "perspective" => "perspectives",
0
+
0
+ "photo" => "photos",
0
+ "status_code" => "status_codes",
0
+
0
+ "house" => "houses",
0
+ "virus" => "viruses",
0
+ "portfolio" => "portfolios",
0
+
0
+ "matrix_fu" => "matrix_fus",
0
+
0
+ "axis" => "axes",
0
+
0
+ "shoe" => "shoes",
0
+
0
+ "horse" => "horses",
0
+ "edge" => "edges",
0
+
0
+ "cow" => "kine"
0
+ }
0
+
0
+ SingularToPlural.each do |single_word, plural_word|
0
+ it "pluralizes #{single_word} => #{plural_word}" do
0
+ single_word.plural.should == plural_word
0
+ end
0
+ end
0
 end
...
127
128
129
130
131
 
 
132
133
134
...
482
483
484
 
 
 
 
485
...
127
128
129
 
 
130
131
132
133
134
...
482
483
484
485
486
487
488
489
0
@@ -127,8 +127,8 @@ describe Language::English::Inflect, "#singular" do
0
     "torpedoes".singular.should == "torpedo"
0
   end
0
 
0
- it "singularizes quizes => quiz" do
0
- "quizes".singular.should == "quiz"
0
+ it "singularizes quizzes => quiz" do
0
+ "quizzes".singular.should == "quiz"
0
   end
0
 
0
   # used to be a bug exposed by this specs suite,
0
@@ -482,4 +482,8 @@ describe Language::English::Inflect, "#singular" do
0
   it "singularizes spams => spam" do
0
     "spams".singular.should == "spam"
0
   end
0
+
0
+ it "singularizes rice => rice" do
0
+ "rice".singular.should == "rice"
0
+ end
0
 end

Comments