here's a start:
harp:~ > cat a.rb
def snake_case string
return string unless string =~ %r/[A-Z]/
string.reverse.scan(%r/[A-Z]+|[^A-Z]*[A-Z]+?|[^A-Z]+/).reverse.map{|word|
word.reverse.downcase}.join '_'
end
Can we agree that "ABCde" => "ab_cde"?
sure. it's arbitrary i realize - but i make sense to me! ;-)
I still get an error when the original string has underscores in it:
"foo_Bar" => "foo__bar"
"foo_BAR" => "foo__bar"
Too tired to figure out a solution right now, I'll get back to you in the
morning (that'll probably be your night.)
ok. i actually use this method in some production code so a better impl would
be nice!
here's the latest, which fixes bug above:
harp:~ > cat a.rb
def snake_case string
return string unless string =~ %r/[A-Z]/
reversed_words = string.reverse.scan(%r/[A-Z]+|[^A-Z]*[A-Z]+?|[^A-Z]+/)
reversed_words.reverse.map{|word| word.reverse.downcase}.join('_').gsub(%r/_+/,'_')
end
def camel_case string
return string if string =~ %r/[A-Z]/ and string !~ %r/_/
words = string.strip.split %r/\s*_+\s*/
words.map!{|w| w.downcase.sub(%r/^./){|c| c.upcase}}
words.join
end
if $0 == __FILE__
require 'test/unit'
require 'enumerator'
class T < Test::Unit::TestCase
tests = {
"snake_case" => %w[
ThisIsSomeString this_is_some_string
fooBar foo_bar
FooBar foo_bar
Foo foo
Foo_Bar foo_bar
foo_Bar foo_bar
foo_BAR foo_bar
],
"camel_case" => %w[
this_is_some_string ThisIsSomeString
foo_bar FooBar
foo Foo
foo_bar_foobar FooBarFoobar
]
}
tests.each do |meth, list|
testno = -1
list.each_slice(2) do |arg, expected|
define_method "test_#{ meth }_#{ testno += 1 }" do
actual = send meth, arg
assert_equal expected, actual
end
end
end
end
end
harp:~ > ruby a.rb
Loaded suite a
Started
...........
Finished in 0.003574 seconds.
11 tests, 11 assertions, 0 failures, 0 errors
-a