37

I'm running Rails 2.3.2.

How do I convert "Cool" to "cool"? I know "Cool".downcase works, but is there a Ruby/Rails method that does the opposite of capitalize, i.e., uncapitalize or decapitalize?

Jacob Relkin
  • 161,348
  • 33
  • 346
  • 320
ma11hew28
  • 121,420
  • 116
  • 450
  • 651

11 Answers11

120

There is also:

"coolat_cat".camelize(:lower) # => "coolCat"
gerry3
  • 21,420
  • 9
  • 66
  • 74
tfischbach
  • 3,003
  • 3
  • 22
  • 16
  • 2
    This does require ActiveRecord tho : http://apidock.com/rails/String/camelize (After reading the question, it does state it is already with Rails) – Ian Vaughan May 28 '13 at 21:51
  • 3
    @Ian Vaughan: ActiveSupport to be more precise – tfischbach May 29 '13 at 10:26
  • They updated the method signature around v4.2.7. It now takes a boolean, like `camelize(uppercase_first_letter = true)` http://apidock.com/rails/v4.2.7/String/camelize – animatedgif Nov 15 '16 at 03:39
  • 1
    @animatedgif there's two methods, [Inflector.#camelize(term, uppercase_first_letter)](http://www.rubydoc.info/gems/activesupport/4.2.7.1/ActiveSupport/Inflector#camelize-instance_method) which takes a string to camelize and a boolean, [String#camelize(first_letter)](http://www.rubydoc.info/gems/activesupport/4.2.7.1/String#camelize-instance_method) which camelizes `self` and takes a symbol `:upper` or `:lower`. I think the apidock docs are in error. – David Moles Dec 15 '16 at 18:40
  • Definitely a rails thing but damn its nice to have! – Dan Bradbury Mar 13 '17 at 20:25
52

There is no inverse of capitalize, but you can feel free to roll your own:

class String
  def uncapitalize 
    self[0, 1].downcase + self[1..-1]
  end
end
Jacob Relkin
  • 161,348
  • 33
  • 346
  • 320
11

You could also do this with a simple sub:

"Cool".sub(/^[A-Z]/) {|f| f.downcase }
JP.
  • 5,507
  • 15
  • 59
  • 100
9
str = "Directly to the south"
str[0] = str[0].downcase
puts str
#=> "directly to the south"
boulder_ruby
  • 38,457
  • 9
  • 79
  • 100
  • This not only the most readable method, but also and by far the most performant one, even if you protect it by some kind of ternary operator or if statement to ensure that str is not nil. This should be the accepted answer. Thanks @boulder_ruby – Freddo Apr 10 '16 at 01:06
5

There is no real inverse of capitalize, but I think underscore comes close.

"CoolCat".underscore  #=> "cool_cat"
"cool_cat".capitalize #=> "Cool_cat"
"cool_cat".camelize   #=> "CoolCat"

Edit: underscore is of course the inverse of camelize, not capitalize.

iain
  • 16,204
  • 4
  • 37
  • 41
3

You can use tap (so that it fits on one line):

"JonSkeet".tap { |e| e[0] = e[0].downcase } # => "jonSkeet"
Jon Schneider
  • 25,758
  • 23
  • 142
  • 170
Benjamin Crouzier
  • 40,265
  • 44
  • 171
  • 236
2

There is an inverse of capitalize called swapcase:

"Cool Cat".swapcase   #=> "cOOL cAT"
Nitin Savant
  • 931
  • 1
  • 8
  • 19
2

String#downcase_first (Rails 7.1+)

Starting from Rails 7.1, there is a String#downcase_first method:

Converts the first character to lowercase.

For example:

'If they enjoyed The Matrix'.downcase_first # => "if they enjoyed The Matrix"
'I'.downcase_first                          # => "i"
''.downcase_first                           # => ""

Sources:

Marian13
  • 7,740
  • 2
  • 47
  • 51
1
name = "Viru"

name = name.slice(0).downcase + name[1..(name.length)]
Danila Ganchar
  • 10,266
  • 13
  • 49
  • 75
Navnath
  • 19
  • 2
1

Try this

'Cool'.sub(/^([A-Z])/) { $1.tr!('[A-Z]', '[a-z]') }

https://apidock.com/ruby/XSD/CodeGen/GenSupport/uncapitalize

Rahul Patel
  • 1,386
  • 1
  • 14
  • 16
1

If you use Ruby Facets, you can lowercase the first letter:

https://github.com/rubyworks/facets/blob/master/lib/core/facets/string/uppercase.rb

rmk
  • 4,395
  • 3
  • 27
  • 32