20

Quick question.

How can I test a word to see if it is singular or plural?

I'd really like:

test_singularity('word') # => true
test_singularity('words') # => false

I bet rails is capable!

Thanks.

doctororange
  • 11,670
  • 12
  • 42
  • 58

3 Answers3

22

Well in rails, you can do a string#singularize|#pluralize comparison to return a true or false value.

But I would think due to the nature of language itself, this might need some backup to do be completely accurate.

You could do something like this

def test_singularity(str)
  str.pluralize != str && str.singularize == str
end

But to see how accurate, I ran a quick set of words.

%w(word words rail rails dress dresses).each do |v|
  puts "#{v} : #{test_singularity(v)}"
end

word : true
words : false
rail : true
rails : false
dress : false
dresses : false

I was a little surprised actually, since 'dress' does get pluralized properly, but when it goes through the #singularize it runs into a bit of a snag.

'dress'.pluralize # => dresses
'dress'.singularize # => dres
Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
nowk
  • 32,822
  • 2
  • 35
  • 40
  • 2
    The "dress".singularize issue is solved here: https://rails.lighthouseapp.com/projects/8994/tickets/2399-incorrect-inflectors-for-business-or-ness#ticket-2399-5 – kikito Nov 26 '09 at 11:53
9

Most of the times i never test for singularity or plural, i just convert it to the singular or plural form i require.

In Rails 2.3.x this was possible, writing something like this

plural_form = org_word.singularize.pluralize
singular_form = org_word.pluralize.singularize

Working further on this, a working function is easy to supply:

require 'active_support'

def is_singular?(str)
  str.pluralize.singularize == str
end


%w(word words rail rails dress dresses).each do |v|
  puts "#{v} : #{is_singular?(v)}"
end

which gives the following output:

word : true
words : false
rail : true
rails : false
dress : true
dresses : false

In Rails 4, with the given words, it is now much easier. You can just do

plural_form = org_word.pluralize
singular_form = org_word.singularize

and thus the function becomes much easier as well:

require 'active_support'

def is_singular?(str)
  str.singularize == str
end
nathanvda
  • 49,707
  • 13
  • 117
  • 139
  • The "dress".singularize issue is solved here: https://rails.lighthouseapp.com/projects/8994/tickets/2399-incorrect-inflectors-for-business-or-ness#ticket-2399-5 – kikito Nov 26 '09 at 11:54
  • Inflectors make sure that the plural or singular can be defined for difficult cases. For instance: for valve it is necessary. But most of the times you only want to singularize and pluralize models? So those cases will be corrected already (or your routes would be messed up). But my routine did return the right answer for dress/dresses. – nathanvda Nov 26 '09 at 14:10
  • Why do you cast to plural first? – NotSimon Aug 27 '14 at 16:39
  • At the time this was the failsafe way, for me, to get the correct form. I haven't tried this in current rails. Did you see how old this answer is? :) – nathanvda Aug 28 '14 at 19:14
  • I tried in rails 4 and updated my answer accordingly. You are right @Simon, it is no longer needed. – nathanvda Aug 28 '14 at 19:22
  • Haha, I hadn't actually looked at the date, still helpful to me though! – NotSimon Aug 30 '14 at 09:37
1

Neither ruby nor rails come with a specific method for testing for "plurality" on words.

As nowk said, the most you can do is implement them yourself, comparing with word.pluralize and word.singularize. This will give you a quick-and-cheap-and-generally-good way of testing. It will fail some times, though.

If you need more precision, you will need to use the Ruby Linguistics gem, which can deal with dress and dresses properly (but it's heavier).

kikito
  • 51,734
  • 32
  • 149
  • 189
  • actually, the singularize stuff isn't included by default on rails, but can be solved via an inflector. See my comments on other posts. – kikito Nov 26 '09 at 11:55