Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

ActiveSuport::Inflector#parameterize should strip leading/trailing dashes

#1034

Attached is the patch that modifies ActiveSupport::Inflector#parameterize to remove leading and trailing dashes from a string.

Before patch:

"check this out!".parameterize
=> "check-this-out-" # note the trailing dash - not cool

After patch:

"check this out!".parameterize
=> "check-this-out" # nice and clean

Reported by Adam Cigánek · September 12th, 2008 @ 02:03 PM

State: committed
Milestone: none
Assigned to: Michael Koziarski Michael Koziarski
Importance: none

Activity

  1. Henrik Nyh
    Henrik Nyh

    Great initiative.

    But consider that the separator can be configured, so hard-coding it for dashes is not optimal. So /...#{Regexp.escape(sep)}.../ might be a better idea.

    Also, while this method is improved, squeezing of the separator should probably be added – so "foo - bar" becomes "foo-bar" and not "foo---bar".

    http://github.com/henrik/slugalizer has all this implemented, with tests.

    The squeezing part won't translate directly to the Rails code because Slugalizer limits the separator to a single character, and Rails parameterize doesn't. So either Rails could be made to limit it to one character, or the squeeze could be rewritten as a regexp.

    September 12th, 2008 @ 04:49 PM

  2. Adam Cigánek
    Adam Cigánek

    You are right about the separator. I'll post another patch soon.

    The squeezing is already there, but it seems that there are no tests for it. I'll add some.

    I didn't know about slugalizer. What about making it part of rails and doing all this stuff with it?

    September 12th, 2008 @ 05:09 PM

  3. Henrik Nyh
    Henrik Nyh

    Cool, thanks. Slugalizer is very similar to the current version of parameterize. Copying the Slugalizer wholesale would save some work -- the Rails team are free to do so.

    On Fri, Sep 12, 2008 at 6:09 PM, Lighthouse support@lighthouseapp.comwrote:

    September 12th, 2008 @ 05:15 PM

  4. Adam Cigánek
    Adam Cigánek

    Ok, great,

    So this is a new patch that replaces the original code of parameterize with code from slugalizer (just slightly modified for readability). It also adds few more tests.

    September 12th, 2008 @ 05:42 PM

  5. Adam Cigánek
  6. Michael Koziarski
    Michael Koziarski
    • Assigned user set to Michael Koziarski
    • Tag changed from activesupport, patch to activesupport, patch
    • Milestone cleared.

    Hey there,

    This doesn't apply cleanly anymore as I've merged all manfred's MB changes. Can you rebase and reupload as a single diff, then I'll apply it.

    September 22nd, 2008 @ 09:04 PM

  7. Adam Cigánek
  8. Repository
    Repository
    • State changed from new to committed

    (from [a4f2ba8fb3c46ef9f7e31725849efdcb1a22c72d]) Modified ActiveSupport::Inflector#parameterize with code from slugalizer (http://github.com/henrik/slugali...

    Handles trailing and leading slashes, and squashes repeated separators into a single character.

    Signed-off-by: Michael Koziarski michael@koziarski.com [#1034 ActiveSuport::Inflector#parameterize should strip leading/trailing dashes state:committed] http://github.com/rails/rails/co...

    September 23rd, 2008 @ 07:10 AM

  9. Rick
    Rick
    • State changed from committed to open

    I've got a slight modification to the patch to that parameterizes something like Fool's Errand to fools-errand, instead of fool-s-errand. I personally prefer that over the current behavior.

    I also noticed that PermalinkFu was about 10x faster. I did what I could to speed it up, but it all came down to the #mb_chars method. Replacing .mb_chars.normalize(:kd) with Iconv.iconv('ascii//translit//IGNORE', 'utf-8', string).to_s helped things immensely. I left it out of this patch though, I didn't know if there was some reason why the rails multibyte support was preferred over Iconv.

    September 25th, 2008 @ 07:59 AM

  10. Rick
  11. Michael Koziarski
    Michael Koziarski

    Is iconv available on all platforms we support?

    I also believe that iconv had some strange behaviour with cases Adam's aware of?

    September 25th, 2008 @ 08:21 AM

  12. Henrik Nyh
    Henrik Nyh

    On Linux (at least some Linuxes, but not OS X), iconv will not properly decompose characters, so "föö" will become "foo" on OS X but "f" on Linux.

    Have noticed this myself, and also seen it mentioned here: http://blade.nagaokaut.ac.jp/cgi...

    September 25th, 2008 @ 09:10 AM

  13. Michael Koziarski
    Michael Koziarski

    a 10x performance difference is quite considerable though, so the iconv version could be worth considering...

    September 25th, 2008 @ 09:52 AM

  14. Henrik Nyh
    Henrik Nyh

    One possibility is to sniff for OS or something else (if someone can figure out exactly where the issue lies) and use different normalizers based on that. Obviously this would make the code more convoluted.

    Might not be a huge win in practice, though, since I would guess a lot of people use OS X (which can use iconv) for dev only, and Linux (which would not use iconv) for production. Then again faster dev is always nice, if you would use this method enough to notice.

    Another possibility is to match the input string against some regexp and run it through iconv if it only contains characters iconv can handle. So people who only ever do unaccented strings get speed, and people who work with the full Unicode palette get their decomposition. Also more convoluted, and not sure it would make for a net speedup, but seems likely.

    September 25th, 2008 @ 10:05 AM

  15. Adam Cigánek
    Adam Cigánek

    Iconv has more robust transliteration. For example, the German character "ß" is transliterated as "ss" in Iconv (which is correct), but is simply removed if mb_chars.normalize(:kd)... is used. There are several more characters like this, that does not contain any diacritics, but are still outside of 7-bit ascii set.

    This can be fixed by creating custom transliteration table for these characters, but that would be messy.

    So Iconv is better solution, but has issues on some platforms as Henrik pointed out (i've also noticed this in the past). Not sure what to do with it though...

    September 25th, 2008 @ 10:18 AM

  16. Michael Koziarski
    Michael Koziarski

    We could also extract the normlization and transliteration into another inflector method, and isolate the optimisations in there?

    We already do something similar to this with sanitize where if there's no "<" chars we return the string unmodified.

    September 25th, 2008 @ 10:23 AM

  17. Henrik Nyh
    Henrik Nyh

    Sounds like a good idea.

    September 25th, 2008 @ 03:25 PM

  18. Michael Koziarski
    Michael Koziarski

    OK, so we need a name for the 'asciify' method (not asciify ;)) and a suggested test for choosing between the two options.

    We can do it when the file is required, so it doesn't have to be fast.

    September 25th, 2008 @ 05:00 PM

  19. Adam Cigánek
    Adam Cigánek

    OK, so we need a name for the 'asciify' method (not asciify ;))

    What about transliterate?

    September 25th, 2008 @ 05:35 PM

  20. Michael Koziarski
    Michael Koziarski

    Quick proof of concept for transliterate. Needs tidying up before it's applied but hopefully it doesn't break anyone's stuff.

    Can you guys tests with your platforms where iconv is broken.

    Plus, will require 'iconv' always work? if not what situations are there where it's broken?

    September 29th, 2008 @ 04:40 PM

  21. Repository
    Repository
    • State changed from open to committed

    (from [5556db22c57294a9f4e2ee4e633834ec6a200242]) Reduce memory usage slightly in String#parameterize

    [#1034 ActiveSuport::Inflector#parameterize should strip leading/trailing dashes state:committed] http://github.com/rails/rails/co...

    October 7th, 2008 @ 08:02 PM