If we assume for a moment that email
is a Ruby object, the first example calls the greeting
method on it. This method could be anything,
perhaps it adds a custom greeting to any email you are writing. In the second example, we chain the greeting
and salutation
methods so that
they both act on email
one at a time, in order. So if salutation
performs a similar function to greeting
, first your email gains
a greeting and then a salutation all in one call. Using method chaining, there are many powerful functions Ruby can perform with minimal coding, such as complex database
queries. Ruby has tons of built-in methods to help with common coding situations. Let's think back the problems we had before when it came to mixing data types.
var1 = 5
var2 = '5'
puts var1 + var2
In this code Ruby would throw an error if we tried to run it. That's because we are trying to mix digits and numbers and computers don't like that. Ruby has two helpful methods for this situation .to_i
and .to_s
. The .to_i
method (short for 'to integer') takes strings and if possible converts them to integers. As you might have guessed, the .to_s
method takes numbers and converts them to strings. If we apply them to the example Ruby will output the number 10
for the first line, and the digit 55
for the second.
puts var1 + var2.to_i
puts var1.to_s + var2
In order to write more powerful programs, let's examine two more built-in Ruby methods gets
and .chomp
. The puts
method stands for 'put string', so what would you reckon gets
stands for? If you said 'get string', you're right (but I'll remind you that you are now talking to your computer screen). This method gets input from the user. Frequently paired with gets
is the .chomp
method. This method removes any carriage returns (you know, the symbol your Enter
key actually types) from the end of the user input. Without .chomp
, all user input would have line breaks where they don't belong!. See what happens if I leave out .chomp
:
puts "What is your name?"
name = gets
puts "I've always thought #{name} was a cute name."
What is your name?
Bob
I've always thought Bob
was a cute name.
Any data we get from the user will be polluted by that darn carriage return! This looks much better:
puts "What is your name?"
name = gets.chomp
puts "I've always thought #{name} was a cute name."
What is your name?
Jill
I've always thought Jill was a cute name.
Not only does this look better but the data functions better as well. Now we can use the gets
method (along with .chomp
) to write another little program. Try it at home if you've already installed RubyMine.
puts "What's your first name?"
first_name = gets.chomp
first_name.capitalize!
puts "So that was #{first_name}, right?"
puts "What's your last name?"
last_name = gets.chomp
last_name.capitalize!
puts "#{last_name}? Did I get that right?"
puts "What city do you live in?"
city = gets.chomp
city.capitalize!
puts "And you live in #{city}?"
puts "What state is that in? (use postal abbreviation)"
state = gets.chomp
state.upcase!
puts "Ok so your name is #{first_name} #{last_name} and you live in #{city}, #{state}?"
puts "Good now get out of my house!"
In this program, an irate homeowner interrogates an intruder, but they do so using lots of the things we've just learned! We print strings, prompt the user for input, store that input in a variable, and format it using the .capitalize!
and .upcase!
methods. It is worth noting that both of those methods end with exclamation marks. This tells Ruby to format the actual objects themselves. If we were to omit the exclamations, Ruby would make a temporary copy of the object with the method applied. Consider these two code snippets:
bruce_wayne = 'batman'
puts bruce_wayne
puts bruce_wayne.capitalize
puts bruce_wayne
edward_nigma = 'riddler'
puts edward_nigma
puts edward_nigma.capitalize!
puts edward_nigma
The first snippet has us printing out a variable with a string in it. Then we call capitalize
on our variable and print it. Then we print the variable again. The output looks like this:
batman
Batman
batman
Notice that the .capitalize
method did not permanently change the string inside of the variable bruce_wayne
. If it had, when we printed the variable again it would have still outputted Batman
. In the second example we used .capitalize!
instead of the exclamation-less variant, and this is the output:
riddler
Riddler
Riddler
Here the string inside the variable edward_nigma
remains capitalized after running the .capitalize!
method because Ruby knew to call the method on the actual object, not just a copy.
So far we have only talked about methods that are built into Ruby. There are many, many such methods and you need only do a quick erm...something search of the web to find pages and pages of them with full documentation on their uses. You may not be surprised, however, to learn that the most powerful methods are the ones you write yourself. In the next lesson you will learn how to wield Ruby methods like a master, but first a brief exploration of control flow.
The power of our Ruby programs flows from the logic underlying them. Let's start with the basics though. In order to compare two objects in Ruby we use comparison methods. Here are some I'm sure you are familiar with:
12 == 3 * 4 #is equal to
-10 < 1 #less than
5.234 > 0.3 #greater than
7.00 <= 7.01 #less than or equal to
9324 >= 2 #greater than or equal to
19 != 0.3 #not equal to
The result of a comparison method is a boolean value of true
(in cases the expression is true) or false
(in cases the expression is not true). Boolean values are very useful in programming. Imagine you are making a shopping app, doesn't it make sense that customers are only able to purchase items that are currently in stock?
We achieve this underlying logic by using control flow in our programs. The most basic form of which comes from the use of if
, else
, elsif
, and unless
.
The if
conditional takes an expression like 4 < 5
and evaluates it for truth. If the expression is true, whatever block of code after the if
will execute. If it's not true, Ruby skips it and goes on to the next part of the code. Any if
must be paired with an end
in order to tell Ruby when the conditional is finished.
puts "Have you considered where you are going to code for eternity?"
answer = gets.chomp
if answer == 'yes'
puts "Remember Ruby is there as your guide."
end
In this example we see the if
in action. We save user input into a variable and then compare it to a string value 'yes'
. Then, only in the case that the user input is equivalent to our chosen value will the expression evaluate as true. When the expression is true, the code block between if
and end
executes.
If we want to evaluate two possibilites we can add an else
to the statement.
if 3 > 4
puts 'Duh-doi!'
else
puts 'Duh! Duh-doi!'
end
Similarly, if we want to expand beyond only evaluating two possibilities we can use the powerful elsif
. Like if
, elsif
takes a boolean expression as an argument. This is just another way of saying that the code block inside the elsif
branch only executes if the expression is true.
x = 4
y = 9
if x < y
puts "x is less than y!"
elsif y < x
puts "y is less than x!"
else
puts "y is equal to x!"
end
In this example we see that Ruby will output x is less than y!
after evaluating the conditionals. Finally, we sometimes want to be able to check for falsehood as much as truth. We could reverse our current conditional setup, but luckily Ruby has a powerful unless
statement for such situations.
hungry = false
puts "I'm so full!" unless hungry
Ruby interprets this code to mean "print this string only when the condition is false". Notice that here we see very different syntax than before. Instead of wrapping a code block between an if
and an end
, Ruby is able to execute this code using only one line. And in case you are wondering, of COURSE we can use this syntax with other conditionals.
puts 'Obviously' if 4 > .2
Here we see our standard if
conditional in this new form. This is a great example of how relaxed syntax rules allow Ruby to be flexible in accomodating to your needs.
Follow along in the video below as I guide you through examples from this lesson as well as another mini project!