piotrmurach / strings-inflection

Convert between singular and plural forms of English nouns
MIT License
31 stars 3 forks source link

Irregular plural words: plural? and plural both fail (people => peoples) #3

Open DannyBen opened 4 years ago

DannyBen commented 4 years ago

Of course you also have a gem for string inflection...

You are my one stop shop for "gem supplies" 🛒

Problem

Strings::Inflection.plural? on irregular plurals fails.

Reproduction

require 'strings-inflection'
require 'strings/inflection/extensions'
using Strings::Inflection::Extensions

# These fail
p 'people'.pluralize == 'people' # => false
p 'people'.plural? == true       # => false
p 'children'.plural? == true     # => false

# These are all ok, just here as a "full test suite"
p 'person'.singular? == true    
p 'child'.singular? == true     
p 'people'.singular? == false   
p 'children'.singular? == false 
p 'person'.plural? == false     
p 'child'.plural? == false

Additional information

The underlying root cause of this problem, is that the gem returns "peoples" as the plural form of people, which is wrong. In ActiveSupport Inflector, it is returned properly:

>> require 'active_support/inflector'
=> true
>> "people".singularize
=> "person"
>> "people".pluralize
=> "people"
piotrmurach commented 4 years ago

Thanks for reporting this! This gem is part of the strings family that I'm trying to put together. It's relatively young so still has some rough edges and growing to do 😉

Do you have time to look into this? There are regexes for irregular nouns that need tweaking. Or a better method to detect singular vs plural. Any help appreciated.

DannyBen commented 4 years ago

I will take a look.

DannyBen commented 4 years ago

Well - I found the problem, I have no idea how to untangle it.

  1. The #plural? method compares the word to its plural form:

https://github.com/piotrmurach/strings-inflection/blob/b51b34d1a49853653303725122fbcc0f3ede9233/lib/strings/inflection/term.rb#L64-L68

  1. The #plural of people is currently returned as peoples, which is not equal to the input word people.

  2. The Noun#plural method, uses Nouns#plurals - the condition below returns peoples when hitting find_match(Nouns.plurals)

https://github.com/piotrmurach/strings-inflection/blob/b51b34d1a49853653303725122fbcc0f3ede9233/lib/strings/inflection/noun.rb#L50-L55

  1. This is due to the "catch all" rule in the @plural_rules, which just adds s to everything.

https://github.com/piotrmurach/strings-inflection/blob/b51b34d1a49853653303725122fbcc0f3ede9233/lib/strings/inflection/nouns.rb#L679

walterdavis commented 4 years ago

I think that this inflector is being more general here, thinking of it as in "the Inuit people" versus "the indigenous peoples of the Arctic region". I admit that's quite a stretch. Perhaps you need to add an inflector rule for that word. Perhaps ActiveSupport already does this and we're not used to seeing the need.

Walter

On May 15, 2020, at 12:25 PM, Danny Ben Shitrit notifications@github.com wrote:

Well - I found the problem, I have no idea how to untangle it.

• The #plural? method compares the word to its plural form: https://github.com/piotrmurach/strings-inflection/blob/b51b34d1a49853653303725122fbcc0f3ede9233/lib/strings/inflection/term.rb#L64-L68

• The #plural of people is currently returned as peoples, which is not equal to the input word people.

• The Noun#plural method, uses Nouns#plurals - the condition below returns peoples when hitting find_match(Nouns.plurals)

https://github.com/piotrmurach/strings-inflection/blob/b51b34d1a49853653303725122fbcc0f3ede9233/lib/strings/inflection/noun.rb#L50-L55

• This is due to the "catch all" rule in the @plural_rules, which just adds s to everything. https://github.com/piotrmurach/strings-inflection/blob/b51b34d1a49853653303725122fbcc0f3ede9233/lib/strings/inflection/nouns.rb#L679

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or unsubscribe.

DannyBen commented 4 years ago

The root cause of this issue is that the gem does not properly handle pluralization of already pluralized irregular words. I have updated the issue description with more info.

piotrmurach commented 4 years ago

Thanks, @DannyBen for investigating. I think the root cause is not necessarily pluralization of plural words, but more precise, pluralization of irregular plural words.

Strings::Inflection.pluralize("words") # => "words"
Strings::Inflection.pluralize("mice") # => "mices"

As far as I can see the solution is to add irregular plurals that are already plural to the list:

[/people\z/, "people"]

@walterdavis It's not that sophisticated 😄 Though it's already much more powerful that ActiveSupport, it handles plenty irregular forms:

Strings::Inflection.pluralize("goose") # => "geese"
ActiveSupport::Inflector.pluralize("goose") #=> "gooses"
piotrmurach commented 4 years ago

Sorry for closing - pressed mouse somehow with a pointer on 'close and comment'...