Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Fix underscore inflector handling of namespaced and adjacent acronyms #14146

Merged
merged 1 commit into from

6 participants

@chewi

The underscore inflector regular expression was not working correctly
for namespaced acronyms that were not entirely uppercased
(e.g. HTTP::RESTful) or adjacent acronyms (e.g. APIRESTful).

I suspect that positive lookbehind would have been used in the
original implementation had it been available in supported Ruby
versions at the time. Now that Rails requires Ruby 1.9.2 or above,
this is no longer an issue.

Thanks to Pawel Kozlowski (khozlov) for highlighting the namespace
issue in #8571.

@senny
Owner

/cc @fxn

@robin850
Collaborator

(I take the liberty to link to a related patch : #12510)

@fxn fxn was assigned by matthewd
@agios

It would be nice to get this fixed, the first pr is already almost 2 years old...
:+1:

@chewi

Since I posted this a while ago, I'd like to add that I have monkey patched this into a number of my projects and have not seen a single issue.

@matthewd
Collaborator

Does this fix something more than ccbb481?

@chewi chewi Fix underscore inflector handling of adjacent acronyms
I suspect that positive lookbehind would have been used in the
original implementation had it been available in supported Ruby
versions at the time. Now that Rails requires Ruby 1.9.2 or above,
this is no longer an issue.

This fixes #14146 for acronyms such as APIRESTful. This technique also
addresses namespaced acronyms that are not entirely uppercased. This
was broken when the commit was originally written but has since been
fixed in ccbb481. The latter does not deal with adjacent acronyms so
this commit wins.
6a8464f
@chewi

Just tried your fix against mine for the various test cases. Yours deals with the "namespaced" acronyms but not the "adjacent" acronyms. My fix deals with both, including the test case you added. I have now rebased and pushed.

@matthewd matthewd merged commit 6a8464f into rails:master
@matthewd
Collaborator

:+1:. I've merged it with a slightly more minimal change to the spelling, just because paranoia. .. and because it makes it easier to see exactly what had to change, if we do run into any weird compatibility issues.

But this seems quite safe -- for strings of this particular form, the previous implementation was mangling them badly, so it seems unreasonable for people to have been depending on same. And I think it's better to get this change into the same release as ccbb481, rather than make similarly incremental adjustments in two releases in a row.

/cc @fxn

(merged as cf66278, then fixed for 1.9 in cad6359)

@chewi

I didn't realise my version could be made simpler using \b. I thought I'd already tried that actually but it seems to work. Thanks!

@sachin004 sachin004 referenced this pull request from a commit in sachin004/rails
@chewi chewi Fix underscore inflector handling of adjacent acronyms
I suspect that positive lookbehind would have been used in the
original implementation had it been available in supported Ruby
versions at the time. Now that Rails requires Ruby 1.9.2 or above,
this is no longer an issue.

This fixes #14146 for acronyms such as APIRESTful. This technique also
addresses namespaced acronyms that are not entirely uppercased. This
was broken when the commit was originally written but has since been
fixed in ccbb481. The latter does not deal with adjacent acronyms so
this commit wins.
e9f5ac3
@divineforest divineforest referenced this pull request from a commit
@chewi chewi Fix underscore inflector handling of adjacent acronyms
I suspect that positive lookbehind would have been used in the
original implementation had it been available in supported Ruby
versions at the time. Now that Rails requires Ruby 1.9.2 or above,
this is no longer an issue.

This fixes #14146 for acronyms such as APIRESTful. This technique also
addresses namespaced acronyms that are not entirely uppercased. This
was broken when the commit was originally written but has since been
fixed in ccbb481. The latter does not deal with adjacent acronyms so
this commit wins.
f690022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 3, 2014
  1. @chewi

    Fix underscore inflector handling of adjacent acronyms

    chewi authored chewi committed
    I suspect that positive lookbehind would have been used in the
    original implementation had it been available in supported Ruby
    versions at the time. Now that Rails requires Ruby 1.9.2 or above,
    this is no longer an issue.
    
    This fixes #14146 for acronyms such as APIRESTful. This technique also
    addresses namespaced acronyms that are not entirely uppercased. This
    was broken when the commit was originally written but has since been
    fixed in ccbb481. The latter does not deal with adjacent acronyms so
    this commit wins.
This page is out of date. Refresh to see the latest.
View
2  activesupport/lib/active_support/inflector/methods.rb
@@ -91,7 +91,7 @@ def camelize(term, uppercase_first_letter = true)
def underscore(camel_cased_word)
return camel_cased_word unless camel_cased_word =~ /[A-Z-]|::/
word = camel_cased_word.to_s.gsub('::', '/')
- word.gsub!(/(?:([A-Za-z\d])|\b)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{$1}#{$1 && '_'}#{$2.downcase}" }
+ word.gsub!(/(?<=[A-Za-z\d\/]|^)(#{inflections.acronym_regex})(?=\b|[^a-z])/) { "#{'_' unless $`.empty? or $`[-1] == '/'}#{$1.downcase}" }
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2')
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
word.tr!("-", "_")
View
3  activesupport/test/inflector_test.rb
@@ -125,6 +125,9 @@ def test_acronyms
["PhDRequired", "phd_required", "PhD required", "PhD Required"],
["IRoRU", "i_ror_u", "I RoR u", "I RoR U"],
["RESTfulHTTPAPI", "restful_http_api", "RESTful HTTP API", "RESTful HTTP API"],
+ ["HTTP::RESTful", "http/restful", "HTTP/RESTful", "HTTP/RESTful"],
+ ["HTTP::RESTfulAPI", "http/restful_api", "HTTP/RESTful API", "HTTP/RESTful API"],
+ ["APIRESTful", "api_restful", "API RESTful", "API RESTful"],
# misdirection
["Capistrano", "capistrano", "Capistrano", "Capistrano"],
Something went wrong with that request. Please try again.