Ruby Strings - Intermediate
Everything in Ruby is essentially an object, a thing that can be manipulated. These objects are manipulated by methods, sets of expressions that return a value. So, everything in Ruby is either an object or a method.
Many of the commonly used methods associated with strings are self-explanatory. They are easy to remember because their names indicate their actions. For example:
"Hello".capitalize "Hello" "hello".capitalize "Hello" "hello".upcase "HELLO" "HELLO".downcase "hello"
.downcase, are all non-destructive. That is to say, their changes do not persist.
"hello" "hello" string.capitalize "Hello" string "hello" # notice how the original string remained the same string.upcase! "HELLO" # by adding an exclamation point the original string is changed string "HELLO"string =
All three methods have a ( ! ) counterpart (called bang). These bang methods are considered destructive because their changes alter the original strings. This does not mean that only bang methods are destructive, as some methods that don't end in an exclamation point do persist changes (
.pop is one such method).
Ruby treats primitive data types (strings, numbers, etc.) as objects. This treatment significantly enhances its utility and provides many built-in methods for working with simple data. For example, strings can be added together. This is referred to as concatenation. This is a common term used in computer science that simply means, "linking things together in a series."
"Hello " + "world!" "Hello world!" # concatenate the strings "Hello " and "world!"
In a similar manner, a string can be copied by multiplying it with an integer.
"Hola! " * 3 "Hola! Hola! Hola! "
A string can be appended to another string using the append operator.
"what's " "what's " string << "up" "what's up"string =
The individual characters of a string can be referenced by their indices. Remember that like most other programming languages, Ruby uses a zero-based index.
Determine how many characters a string is composed of with the
.size method. Note: this will return the total number of characters including spaces.
"hello how are you doing today".size 29
Specific characters can be deleted from a string with the
.delete method. Simply pass in the character to be deleted as an argument to the method. Ruby removes the specified character and then returns the remaining string. The
.delete method also has a destructive version,
"hello" "hello" string.delete("h") "ello" string.size 5 string.delete!("o") "hell" string.size 4string =
Ruby provides a rich syntax for replacing characters. The simplest method is
.replace, which behaves as expected.
"Fantastic" "Fantastic" string.replace("Terrible") "Terrible" # the contents of 'string' has been replacedstring =
.replace method swaps the entire contents of a string. To replace only certain characters, use the
.sub! methods. The two required arguments are the characters to be replaced, followed by their replacements.
"seven" "seven" value.sub!("even","ix") "six" value "six"value =
.sub method replaces the first instance of characters that it finds. There is a similar substitution method, .gsub, which replaces every instance of the characters. You can remember this by associating
.sub with "substitution" and
.gsub with "global substitution". An example in IRB will make this clearer:
"abc abc abc" "abc abc abc" # sub will 'find & replace' the first instance string.sub("abc", "123") "123 abc abc" string.gsub("abc", "123") "123 123 123" # notice how all instances were changed. remember 'g' for globalstring =
So far we have been specifying the exact characters we want to be replaced. We could greatly expand our search if we used regular expressions to search for a specific sequence of characters. We will cover that topic in detail in a later chapter. Once you understand how to work with regular expressions you will significantly enhance your ability to search and extract data from strings, data structures, and files.
Strings often contain blocks of data. With the
.split method, we can separate these blocks based on a specific delimiter. If no argument is specified as the delimiter then
.split will use spaces ( ' ' ) by default. This is a powerful and widely used method. The first example we'll look at is one string containing three different names. Each name is separated by a space and our goal is to access each name individually.
"Bob Jane Samantha" "Bob Jane Samantha" # we have one string that contains three names names = input.split # we don't specify any arguments, the space character is implied [  "Bob",  "Jane",  "Samantha" ]input =
What if our string contained a group of elements that were separated by something other than spaces? In that case, we can explicitly tell ruby what the delimiter should be.
"one,two,three,four,five" "one,two,three,four,five" numbers = input.split(",") [  "one",  "two",  "three",  "four",  "five" ]input =
Split also takes a second argument, the maximum number of array elements we want returned. This allows us to further customize our returned object. For example:
",", 3) [  "one",  "two",  "three,four,five" ]numbers = input.split(
If there are more elements than the maximum number specified then the remaining elements are grouped together in the final index.
Although we have been using simple strings as the delimiter,
.split can also accept regular expressions. Since regular expressions are covered in a later chapter, we will only briefly explore how they can be used by
.split. In Ruby. we specify a regular expression with forward slashes ( /regex/ ).
"one, two three: four" "one, two three: four" # the string 'input' contains 4 elements separated by a comma, space, and a colon input.split(/\W+/) # this regular expression matches one or more non-word characters # viola! all four elements are returned to us in an array [  "one",  "two",  "three",  "four" ]input =
There may be times when you want to view a human readable version of a variable. Ruby provides the
.inspect method for this very purpose. The
.inspect method is quite versatile in that it is not limited to the string class, but rather, any object.
"Did you know I'm a string?" "Did you know I'm a string?" string.inspect "\"Did you know I'm a string?\""string =
.inspect method always returns a string object. It will often come in handy when you're debugging and you need to "peek" inside of an object. You may not find yourself reaching for inspect often, especially while you are still learning. The point of introducing it is not just to add another method to your repertoire, but rather, familiarize you with different operations built-in to Ruby. It's impossible to memorize every method you come across and that shouldn't be your goal. You can always reference a method if you forget what it does.
Learning a new language is a process. In the beginning, there is a wide gap in what you know and what you need to know. Throughout the process, that gap begins to shrink. Early on, the gap shrinks as a result of a third party, some external source. You may read a book, take a course, or attend a meet-up. You learn something new and the gap narrows. Eventually, you learn enough to begin experimenting and practicing on your own. As problems arise you take a heuristic approach and manage to figure things out by yourself. You may be aware that the solution isn't the most elegant but it doesn't really matter. You are proud of this new found independence and self-sufficiency. Once you begin to use what you already know to find solutions to problems you'll begin closing the gap yourself. It's around this point that you'll realize you are no longer a beginner. You've graduated to some intermediate stage where you have a better command of the language and a greater appreciation for the complexity of what you previously did not understand. Unfortunately, a cruel paradox begins to sink in. The more you understand the more complex you realize everything is and the less you feel like you know. This is a form of what is known as the imposter syndrome, a feeling that's not uncommon in the world of computer science. Do not fret! We shall revisit this feeling again in a later chapter with the intention of understanding where it comes from and how we can overcome it.