I wrote a Ruby script a few months ago which was used to batch-rename
a bunch of files from camel case to underscored, since I couldn't find
a ready made program to do so. I never had to change the way Rails
behaves, but I did base the string conversion stuff on how Rails does
it. Here's my modified "decamelize" which handles acronyms
correctly: (Hopefully it's not too horrible -- it did what I needed
at the time.)
{{{
module Inflector
# Converts converts a camel case string (i.e. CamelCase) to its
decamelized
# version. It makes several special considerations when splitting
into "words".
# For example, "&" is considered a word by itself, as are digits.
(Please refer
# to the unit tests for a completely accurate description.)
#
# Examples:
# "CamelCase" => "Camel_Case"
# "Space Separated" => "Space_Separated"
# "XMLThingy" => "XML_Thingy"
def decamelize
self.to_s.
gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2').
gsub(/([a-z]+)([A-Z\d])/, '\1_\2').
gsub(/([A-Z]{2,})(\d+)/i, '\1_\2').
gsub(/(\d+)([a-z])/i, '\1_\2').
gsub(/(.+?)\&(.+?)/, '\1_&_\2').
gsub(/\s/, '_')
end
end
# And the corresponding tests. You'll have to include Inflector in
String to get them to work:
class StringTest < Test::Unit::TestCase
# Baseline tests generated before using real file names.
def test_decamelize
assert_equal('Hello_World', 'HelloWorld'.decamelize)
assert_equal('This_Is_A_Longer_Test',
'ThisIsALongerTest'.decamelize)
assert_equal('A_Two-fold_Test', 'ATwo-foldTest'.decamelize)
assert_equal('BDSCHED', 'BDSCHED'.decamelize)
assert_equal('XML_Thingy', 'XMLThingy'.decamelize)
assert_equal('YAML_Thingy', 'YAMLThingy'.decamelize)
assert_equal('XML_And_YAML_Thingy', 'XMLAndYAMLThingy'.decamelize)
assert_equal('PHP_And_Perl', 'PHPAndPerl'.decamelize)
assert_equal('UNIX_And_Linux_Are_Different',
'UNIXAndLinuxAreDifferent'.decamelize)
assert_equal('Mac_OS', 'MacOS'.decamelize)
assert_equal("F8796403.tmp", "F8796403.tmp".decamelize)
assert_equal('This_Is_1_Test_With_Numbers',
'ThisIs1TestWithNumbers'.decamelize)
assert_equal('This_has_spaces', 'This has spaces'.decamelize)
end
#
=
=
=
=
=
=
=
=
=
=
=
=
========================================================================
# The following tests (and bugs) were extrapolated from the
initial output of this
# program and its subsequent revisions.
#
=
=
=
=
=
=
=
=
=
=
=
=
========================================================================
def test_decamelize_gives_lowercase_after_numbers
# Bugs:
# oct05coords.doc -> oct_05coords.doc
# 2001payroll.pdf -> 2001payroll.pdf
# w4federal2001.pdf -> w_4federal_2001.pdf
# w4state2000.pdf -> w_4state_2000.pdf
# 457amountchange.pdf -> 457amountchange.pdf
# fy08stratplanweb.doc -> fy_08stratplanweb.doc
# fy08withtasksafter61807coords.doc ->
fy_08withtasksafter_61807coords.doc
# hp4050tnug.pdf -> hp_4050tnug.pdf
# hp4050tngs.pdf -> hp_4050tngs.pdf
# hp4050tnqr.pdf -> hp_4050tnqr.pdf
assert_equal("oct_05_coords.doc", "oct05coords.doc".decamelize)
assert_equal("2001_payroll.pdf", "2001payroll.pdf".decamelize)
assert_equal("w_4_federal_2001.pdf",
"w4federal2001.pdf".decamelize)
assert_equal("w_4_state_2000.pdf", "w4state2000.pdf".decamelize)
assert_equal("457_amountchange.pdf",
"457amountchange.pdf".decamelize)
assert_equal("fy_08_stratplanweb.doc",
"fy08stratplanweb.doc".decamelize)
assert_equal("fy_08_withtasksafter_61807_coords.doc",
"fy08withtasksafter61807coords.doc".decamelize)
assert_equal("hp_4050_tnug.pdf", "hp4050tnug.pdf".decamelize)
assert_equal("hp_4050_tngs.pdf", "hp4050tngs.pdf".decamelize)
assert_equal("hp_4050_tnqr.pdf", "hp4050tnqr.pdf".decamelize)
end
def test_decamelize_surrounds_ampersand_with_underscores
# Bugs:
# CustRelations&AccessStrategies.doc ->
Cust_Relations&Access_Strategies.doc
# Circ&TSFAQ.doc -> Circ&TSFAQ.doc
assert_equal("Cust_Relations_&_Access_Strategies.doc",
"CustRelations&AccessStrategies.doc".decamelize)
assert_equal("Circ_&_TSFAQ.doc", "Circ&TSFAQ.doc".decamelize)
end
def test_decamelize_inserts_underscore_between_uppercase_and_numbers
# Bugs:
# MoviesETV2007.doc -> Movies_ETV2007.doc
# MusicCD2003.doc -> Music_CD2003.doc
# NonfictionDVD2002.doc -> Nonfiction_DVD2002.doc
# PaperbacksAdult&YA2005.doc -> Paperbacks_Adult&YA2005.doc
# AFSCMEContractOLD2003.pdf -> AFSCME_Contract_OLD2003.pdf
# AFSCMEContractOLD2007.pdf -> AFSCME_Contract_OLD2007.pdf
assert_equal("Movies_ETV_2007.doc", "MoviesETV2007.doc".decamelize)
assert_equal("Music_CD_2003.doc", "MusicCD2003.doc".decamelize)
assert_equal("Nonfiction_DVD_2002.doc",
"NonfictionDVD2002.doc".decamelize)
assert_equal("Paperbacks_Adult_&_YA_2005.doc",
"PaperbacksAdult&YA2005.doc".decamelize)
assert_equal("AFSCME_Contract_OLD_2003.pdf",
"AFSCMEContractOLD2003.pdf".decamelize)
assert_equal("AFSCME_Contract_OLD_2007.pdf",
"AFSCMEContractOLD2007.pdf".decamelize)
end
end
}}}
I hope this helps a little.
-- Ben
> --~--~---------~--~----~------------~-------~--~----~
> You received this message because you are subscribed to the Google
> Groups "Iowa City Ruby Group" group.
> To post to this group, send email to ic-...@googlegroups.com
> To unsubscribe from this group, send email to ic-ruby-u...@googlegroups.com
> For more options, visit this group at http://groups.google.com/group/ic-ruby?hl=en
> -~----------~----~----~----~------~----~------~--~---
>