KobbyAdarkwa
KobbyAdarkwa

Reputation: 181

Working with Ruby class: Capitalizing a string

I'm trying to get my head around how to work with Classes in Ruby and would really appreciate some insight on this area. Currently, I've got a rather simple task to convert a string with the start of each word capitalized. For example:

Not Jaden-Cased: "How can mirrors be real if our eyes aren't real"
Jaden-Cased:     "How Can Mirrors Be Real If Our Eyes Aren't Real"

This is my code currently:

class String
  def toJadenCase
    split
    capitalize

  end
end

#=> usual case: split.map(&:capitalize).join(' ')


Output:

Expected: "The Moment That Truth Is Organized It Becomes A Lie.",
 instead got: "The moment that truth is organized it becomes a lie."

Upvotes: 1

Views: 144

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110665

I suggest you not pollute the core String class with the addition of an instance method. Instead, just add an argument to the method to hold the string. You can do that as follows, by downcasing the string then using gsub with a regular expression.

def to_jaden_case(str)
  str.downcase.gsub(/(?<=\A| )[a-z]/) { |c| c.upcase } 
end
to_jaden_case "The moMent      That trUth is organized, it becomes a lie."
  #=> "The Moment      That Truth Is Organized, It Becomes A Lie."

Ruby's regex engine performs the following operations.

(?<=\A| )  : use a positive lookbehind to assert that the following match
             is immediately preceded by the start of the string or a space 
[a-z]      : match a lowercase letter

(?<=\A| ) can be replaced with the negative lookbehind (?<![^ ]), which asserts that the match is not preceded by a character other than a space.

Notice that by using String#gsub with a regular expression (unlike the split-process-join dance), extra spaces are preserved.

When spaces are to be matched by a regular expression one often sees whitespaces (\s) matched instead. Here, for example, /(?<=\A|\s)[a-z]/ works fine, but sometimes matching whitespaces leads to problems, mainly because they also match newlines (\n) (as well as spaces, tabs and a few other characters). My advice is to match space characters if spaces are to be matched. If tabs are to be matched as well, use a character class ([ \t]).

Upvotes: 1

Ayudh
Ayudh

Reputation: 1763

Try:

 def toJadenCase
    self.split.map(&:capitalize).join(' ')
 end

Upvotes: 1

Related Questions