Ruby was written to make the programmer's job easy and not care if the computer's job is hard. In this brief introduction we'll look at the key language features you need to get started.
- Instructions and Interpreters
- Variables
- Methods
- Strings
- Numbers
- Symbols
- Collections
- Arrays
- Hashes
- Conditionals
- Conditional Decisions
- Conditional Looping
- Nil & Nothingness
Ruby is thought of by many as a "new" programming language, but it actually was released in 1994 by a developer known as Matz. Matz is a self-described "language geek" and was a particularly big fan of Perl. His idea for Ruby was to create a language that was flexible and powerful like Perl, but more expressive in its syntax -- even pushing towards English-like readability.
Ruby was released in '94 and it grew an audience quickly -- in Japan. Until 2000 there really wasn't any documentation about the language that wasn't in Japanese, so if you wanted to learn Ruby you were pretty much on your own. Dave Thomas, a pioneer of agile programming, became enamored with Ruby and decided to create that documentation. He wrote what's affectionately known as "The Pickaxe," due to its cover image, which opened Ruby to the English-speaking world.
From there Ruby started growing, though slowly. It became popular with system administrators to write maintenance and "glue" scripts -- the kinds of things Perl had been used for. The US Ruby community numbered in the hundreds from 2000-2005.
In 2004-2005 a Chicago company named 37Signals hired a young CS student to build a web application. They gave him almost total freedom for the implementation; they were only concerned with the design and functionality from the client-side. At the time the predominant web technologies were PHP, Java's JSP, and Microsoft's ASP. They were each somewhat painful, so David, today known as DHH, went his own direction.
He wrote the application in Ruby. He relied on the core language and a handful of helper libraries, but more-or-less created the entire stack himself. He and 37Signals worked on the web app, today known as Basecamp, and released it.
Then, once Basecamp was built, DHH extracted the web framework out of it. This was a very different approach from Java or Microsoft where the web frameworks were handed down from on high and the "real world" had to adapt. Instead, Rails was extracted from the real world. It tried to solve only the necessary problems and defer developing features until they were necessary.
That approach was a big hit and Rails has powered the growth of the Ruby community ever since. Now we have pages and pages of books on Amazon, dozens of conferences around the world, and thousands of people employed as Ruby/Rails developers at organizations like AT&T, NASA, Google, and LivingSocial.
And if you want to learn Rails, you need to learn Ruby first! Here goes...
There are two ways to run Ruby code. You can write one or more instructions in a file then run that file through the Ruby interpreter. When you're writing a "real" program, this is the way to do it. We might have a file named my_program.rb
like this:
class Sample
def hello
puts "Hello, World!"
end
end
s = Sample.new
s.hello
Then we could run the program like this:
$ ruby my_program.rb
Hello, World!
Ruby is called a scripting language or an interpreted language because it doesn't run on the computer's hardware directly, it first goes through the Ruby interpreter. When you run ruby my_program.rb
you're actually loading the ruby
program which in turn loads your my_program.rb
.
The second option is to use the Interactive Ruby Shell -- IRB. When I'm programming I always have IRB open. IRB has all the same features as the regular Ruby interpreter, but it allows you to easily evaluate one or a handful of instructions and instantly see their results. I use IRB mostly for experimenting. In a regular program I might write a hundred lines of instructions. But if there's one thing I'm not sure about I'll flip over to IRB to test it out. Start IRB by opening a Terminal (Mac) or Command Prompt (Win) and typing irb
.
Everything needs a name so we can refer to it. A variable, like in math, is just a name for a piece of data. In Ruby, variables are very flexible and can be changed at any time. Variables are assigned using a single equals sign (=
) where the right side of the equals sign is evaluated first, then the value is assigned to the variable named on the left side of the equals. Go into IRB, enter in these example instructions, and observe the output that Ruby gives you back:
$ a = 5
$ b = 10 + 5
$ c = 15 + a + b
$ b = c - a
What do you think a
equals?
What do you think b
equals?
What do you think c
equals?
What do you think second b
equals?
Here is where Ruby diverges from Algebra, as you can also assign words or text to be stored in a variable.
d = "Hello, "
e = "World!"
f = d + e
What do you think f
equals?
A familiar equation from Algebra is the equation of a line.
y = m * x + b
While learning this equation you likely had an understanding of y and x, but the values m and b were introduced. m is the slope of the line and b is the y-intercept. In ruby you are allowed to give more descriptive names to your variables, so you could rewrite the same equation to be more descriptive.
y = slope * x + y_intercept
Variables names are still restricted to being all lower-case, start with a letter or an underscore _
and can have numbers (but not at the start).
Explore creating some variables with different names that describe yourself, your friends or other things in your world.
Create a variable that:
-
stores a number (like
age
) -
stores some text (like
hometown
) -
that has an underscore _ (like
first_name
) -
that has a number in it (like
favorite_color2
)
What happens when you create a variable name:
-
that starts with a number?
-
that uses a dash - instead of an underscore _?
- Why would you want to use an underscore in your variable names?
While running simple commands in IRB is easy, it becomes tiresome to do anything that spans multiple lines. So we are going to continue from here writing our remaining ruby code in a text file.
- Exit your IRB session
- Note which folder your terminal is currently in, this is your "working directory"
- Using a plain-text editor like Notepad++ or Sublime Text, create a file named
personal_chef.rb
. - Save the file in your editor
- Reopen
irb
from your terminal - Now load the file:
$ load 'personal_chef.rb'
In Ruby, everything is an object. Objects know information, called attributes, and they can do actions, called methods.
For an example of an object, think about you as a human being. You have attributes like height, weight, and eye color. You have methods like "walk", "run", "wash dishes", and "daydream." Different kinds of objects have different attributes and methods. In the next sections we'll look at a few specific kinds of objects common in Ruby.
A class is an abstract idea, it defines what all objects of that type can know and do. Think of the chair you're sitting in. It's not an abstract chair, it is an actual chair. We'd call this actual chair an instance - it is a realization of the idea chair. It has measurable attributes like height, color, weight. The class chair, on the other hand, has an abstract weight, color, and size -- we can't determine them ahead of time.
In Ruby, we define an object using the class
keyword. Here's an example defining the object PersonalChef
:
class PersonalChef
end
Inside the class we usually define one or more methods using the def
keyword like this:
class PersonalChef
def make_toast
puts "Making your toast!"
end
end
Inside the def
and end
lines we'd put the instructions that the chef should perform when we say make_toast
.
Once we define a class, we create an instance
of that class like this:
frank = PersonalChef.new
We're calling the new
method on the class PersonalChef
and storing it into the variable named frank
. Once we have that instance, we can set or get its attributes and call its methods. Methods are called by using this syntax: object.method_name
. So if you have a person named frank
, you would tell him to make toast by calling frank.make_toast
.
-
Copy the above code that defines the
PersonalChef
into your text file. -
In
irb
run the commands:
$ load 'personal_chef.rb'
$ frank = PersonalChef.new
$ frank.make_toast
-
Add a new method named
make_milkshake
onPersonalChef
-
In
irb
run the commands:
$ load 'personal_chef.rb'
$ frank = PersonalChef.new
$ frank.make_toast
$ frank.make_milkshake
-
Create a new class called
Butler
-
Add a method named
open_front_door
onButler
-
Create an
instance
of that class and assign it to a variable namedjeeves
-
In
irb
run the commands:
$ load 'personal_chef.rb'
$ jeeves = Butler.new
$ jeeves.open_front_door
Sometimes methods take one or more parameters that tell them how to do what they're supposed to do. For instance, I might call frank.make_toast('burned')
for him to burn my toast. Or maybe he has another method where I call frank.make_breakfast("toast","eggs")
for him to make both toast and eggs. Parameters can be numbers, strings, or any kind of object. When a method takes a parameter it'll look like this:
class PersonalChef
def make_toast(color)
puts "Making your toast #{color}"
end
end
Where the method is expecting us to pass in a color
telling it how to do the method make_toast
.
-
Copy the above code that defines the
PersonalChef
into your text file. -
In
irb
run the commands:
$ load 'personal_chef.rb'
$ frank = PersonalChef.new
$ frank.make_toast('burnt')
-
Create a
make_milkshake
method, that has a flavor parameter,
flavor
-
In
irb
run the commands:
$ load 'personal_chef.rb'
$ frank = PersonalChef.new
$ frank.make_milkshake('chocolate')
-
Create a new method named
open_door
which accepts a parameter which is the name of the door to open. -
Ask
jeeves
to open the front door, the back door, the closet door. -
In
irb
run the commands:
$ load 'personal_chef.rb'
$ jeeves = Butler.new
$ jeeves.open_door('front')
$ jeeves.open_door('back')
$ jeeves.open_door('closet')
In Ruby, every time you call a method you get a value back. By default, a Ruby method returns the value of the last expression it evaluated. If you called the make_toast
method above, you should have seen the return value nil
. The puts
instruction always returns nil
, so since that was the last instruction in your method, you saw nil
when calling that method.
For the purposes of our next section I'm going to explicitly return the chef instance itself from the method. Imagine you are looking at your chef frank
. You say "Frank, go make my toast", he tells you he's making the toast, then comes back to you to receive more instructions. He's "returning" himself to you. Here's how we implement it in code:
class PersonalChef
def make_toast(color)
puts "Making your toast #{color}"
return self
end
def make_eggs(quantity)
puts "Making you #{quantity} eggs!"
return self
end
end
We do this because we often want to call multiple methods on an object one after the other -- this is called method chaining . Still thinking about frank
, we might want to call make_toast
and make_eggs
one after the other. We can call multiple methods by using the format object.method1.method2.method3
. So for this example, we might say:
frank.make_toast("burned").make_eggs(6)
To read that in English, we're telling frank
to make_toast
with the parameter burned
, then after that is completed telling him to make_eggs
with the parameter 6
.
-
Write a
make_milkshake
method that alsoreturn self
-
Now ask
frank
to make you toast, eggs, and then immediately make you a milkshake -
In
irb
run the commands:
$ load 'personal_chef.rb'
$ frank = PersonalChef.new
$ frank.make_toast('burnt').make_eggs(6).make_milkshake('strawberry')
- Add another
make_toast
,make_eggs
ormake_milkshake
to the end of that line above. Continue to keep adding toast and milkshake orders until you are sick to your stomach.
Remember to reload the file: load 'personal_chef.rb'
In Ruby a string is defined as a quote ("
) followed by zero or more letters, numbers, or symbols and followed by another quote ("
). Some simple strings would be "hello"
or "This sentence is a string!"
. Strings can be anything from ""
, the empty string, to really long sets of text. This whole tutorial, for instance, is stored in a string. Strings have a few important methods that we'll use.
These exercises should be accomplished in IRB
$ greeting = "Hello Everyone!"
$ greeting.length
-
length
Call
length
on a string to get back the number of characters in the string. For instance"hello".length
would give you back5
.
-
Find out the length of your first, middle, and last name
-
Calculate the total length of your name
$ greeting = "Hello Everyone!"
$ greeting.delete('l')
-
delete
Delete lets you specify a set of characters that should be removed from the original string. For instance,
"hello".delete("l")
would give you back"heo"
after deleting all occurrences of"l"
, or"Good Morning!".delete("on")
would give you"Gd Mrig!"
- Pick the letter you hate the most and remove it from your name
$ greeting = "Hello Everyone!"
$ greeting.gsub("Everyone!","Friends!")
-
gsub
Call
gsub
to replace a substring with a different string. For instance,"hello".gsub("ll","y yo")
would give you back"hey yoo"
.
- Change the above the example to say hello just to you.
$ t2 = "sample,data,from,a,CSV"
$ t2.split(",")
-
split
The
split
method is somewhat complex because it's used to break a single string into a set of strings. For instance, I could call"Welcome to Ruby".split(" ")
and it would find the two occurrences of" "
(a blank space) and split the string at those points, giving you back a set like this:["Welcome","to","Ruby"]
Often with strings we want to pull out just a part of the whole -- this is called a substring. Try out these examples in irb
:
$ greeting = "Hello Everyone!"
$ greeting[0..4]
$ greeting[6..14]
$ greeting[6..-1]
$ greeting[6..-2]
The numbers inside the []
brackets specify which of the characters you want pulled out. They're numbered starting with zero. So the first example pulls out the letters from zero, the beginning of the string, up to and including position four. The second example pulls from 6
up to 14
. The third one goes from 6
up to...-1
? If you specify a negative value, that is like counting back from the end. Using -1
means the end of the string, so 6..-1
means "from 6
to the end of the string." The last example goes from 6
to the second to last character in the string.
It is extremely common that we want to combine the value of a variable with other strings. For instance, let's start with this simple example string:
"Happy Saturday!"
When we put that into IRB it just spits back the same string. If we were writing a proper program, we might want it to greet the user when they start the program by saying "Happy"
then the day of the week. So we can't just put a string like "Happy Saturday!"
or it'd be saying Saturday even on Tuesday.
What we need to do is combine a variable with the string. There are two ways to do that. The first and easiest approach is called string concatenation which is basically just adding strings together like this:
$ today = "Saturday"
$ puts "Happy " + today + "!"
In the first line we set up a variable to hold the day of the week, then in the second line we print the string Happy
combined with the value of the variable today
and the string !
. You might be thinking "What was the point of that since we still just wrote Saturday in the first line?" Ok, well, if you were writing a real program you'd use Ruby's built-in date functions like this:
$ require 'date'
$ today = Date.today.strftime("%A")
$ puts "Happy " + today + "!"
String concatenation works fine most of the time, but there is a gotcha that pops up. Try this:
$ today = Date.today.strftime("%A")
$ day_of_year = Date.today.yday
$ puts "Happy " + today + "! It is the " + day_of_year + " day of the year."
You should get an error complaining that Ruby "can't convert Fixnum into String". What does that mean? When Ruby is assembling the parts of that string it sees a string "Happy "
, then a string in the variable today
, then a string with the ! and a few words, then the variable day_of_year
, then the string "day of the year."
.
The problem is that Ruby knows how to add one string to another, but it's not sure how to add a string to a number. day_of_year
contains a number, and when it tries to combine the strings with that number, Ruby isn't sure what to do. Thankfully, numbers have a method which converts them into a string so they can be combined with strings. That method is .to_s
for "to string". Retry your example with this slight change:
$ today = Date.today.strftime("%A")
$ day_of_year = Date.today.yday
$ puts "Happy " + today + "! It is the " + day_of_year.to_s + " day of the year."
Great, no errors and our output looks correct. Having to remember that .to_s
whenever you use a number is a pain, though. There is another combination method that forces the "to string" conversion for you called string interpolation.
String interpolation is the process of sticking data into the middle of strings. We use the interpolation marker #{}
. Inside those brackets we can put any variables or Ruby code which will be evaluated, converted to a string, and output in that spot. Our previous example could be rewritten like this:
$ puts "Happy #{today}! It is the #{day_of_year} day of the year."
If you compare the output you'll see that this second method gives the exact same results. The code itself is a little more compact and I find it much easier to read.
You can also put any Ruby code or calculations inside the brackets when interpolating like this example:
$ modifier = "very "
$ mood = "excited"
$ puts "I am #{modifier * 3 + mood} for today's class!"
Write a good_morning
method on the PersonalChef
object that, when called, prints out a message like "Happy Wednesday, it's the 132 day of 2011."
Symbols are difficult to explain. You can recognize a symbol because it starts with a colon then one or more letters, like :flag
or :best_friend
.
Think of it as a stripped down string that has barely any methods and no string interpolation. Compare the method list for a proper string versus a similar symbol like this:
$ "hello".methods
$ "hello".methods.count
$ :hello.methods
$ :hello.methods.count
Symbols are used for passing information around inside our program. We'd never print a symbol out to a user -- for that we'd use a string.
When starting out with pure Ruby you might not use symbols very frequently. But when you graduate to Ruby on Rails, they are everywhere. If you see an object that looks like :this
, you'll know it's a symbol.
There are two basic kinds of numbers: integers (whole numbers) and floats (have a decimal point). For most programs, you can get away with just integers, and I recommend avoiding floats whenever possible. Integers are much easier for both you and the computer to work with.
You can use normal math operations with integers including +
, -
, /
, and *
. Integers have a bunch of methods to help you do math-related things, which you can see by calling 5.methods
.
A common function in other languages is the for loop, used to repeat an instruction a set number of times. An example:
for(int i=0; i < 5; i++){
printf "Hello, World"
}
But that's not very readable unless you're familiar with the construct. In Ruby, because our integers are proper objects, we have the handy times
method to repeat an instruction a set number of times.
Let's take another look at Frank's make_eggs
method. We can rebuild it to take advantage of the times
method like this:
def make_eggs(quantity)
quantity.times do
puts "Making an egg."
end
puts "I'm done!"
return self
end
In this example we're using the times
method with a do
/end
block. When we call the times
method we need to tell it what to do that number of times. Ruby looks for the starting keyword do
and the ending keyword end
. Each instruction between the do
and end
will be executed this number of times
. Try this example with multiple instructions:
Try reloading the file with load "personal_chef.rb"
and executing the make_eggs
method for frank
.
Usually when we're writing a program it's because we need to deal with a collection of data. There are two main types of collections in Ruby: arrays and hashes.
An array is a number-indexed list. Picture a city block of houses. Together they form an array and their addresses are the indices. Each house on the block will have a unique address. Some addresses might be empty, but the addresses are all in a specific order. The index is the address of a specific element inside the array. In Ruby the index always begins with 0
. An array is defined in Ruby as an opening [, then zero or more elements, then a closing ]. Try out this code:
$ meals = ["breakfast","lunch","dinner"]
$ puts meals[2]
$ puts meals.first
$ puts meals.last
Keep going with these, but note that the first line below should give you some unusual output. Try and understand what Ruby is telling you:
$ puts meals[3]
$ meals << "dessert"
$ puts meals[3]
$ puts meals
In order to get a specific element in the array you use the syntax arrayname[index]
.
There are lots of cool things to do with an array. You can rearrange the order of the elements using the sort
method. You can iterate through each element using the each
method. You can mash them together into one string using the join
method. You can find the address of a specific element by using the index
method. You can ask an array if an element is present with the include?
method. Try adding this method to PersonalChef
that manipulates an array:
def gameplan(meals)
meals.each do |meal|
puts "We'll have #{meal}..."
end
all_meals = meals.join(", ")
puts "In summary: #{all_meals}"
end
We use arrays whenever we need a list where the elements are in a specific order.
To try out Frank with your new gameplan
method, go ahead and load personal_chef.rb
again, instantiate frank
, and try running your array through Frank like so:
$ frank.gameplan(["chicken","beef"])
You can add as many meals to the game plan as you wish! Try this exercise with some of the other methods in your file.
A hash is a collection of data where each element of data is addressed by a name. As an analogy, think about a refrigerator. If we're keeping track of the produce inside the fridge, we don't really care about what shelf it's on -- the order doesn't matter. Instead we organize things by name. Like the name "apples" might have the value 3, then the name "oranges" might have the value 1, and "carrots" the value 12. In this situation we'd use a hash.
A hash is an unordered collection where the data is organized into "key/value pairs". Hashes have a more complicated syntax that takes some getting used to:
$ produce = {"apples" => 3, "oranges" => 1, "carrots" => 12}
$ puts "There are #{produce['oranges']} oranges in the fridge."
The key is used as the address and the value is the data at that address. In the produce
hash we have keys including "apples"
and "oranges"
and values including 12
and 3
. When creating a hash the key and value are linked by the =>
symbol which is called a rocket. So hashes start with a curly bracket {
, have zero or more entries made up of a key, a rocket, and a value separated by commas, then end with a closing curly bracket }
. Try a few more steps:
$ produce["grapes"] = 221
$ produce
$ produce["oranges"] = 6
$ produce
$ produce.keys
$ produce.values
In the first line of those instructions, we add a new value to the hash. Since the "grapes"
key wasn't in the original hash, it's added with the value of 221
. Keys in the hash must be unique, so when we use the same syntax with produce["oranges"]
it sees that the key oranges
is already in the list and it replaces the value with 6
. The keys
and values
methods will also give you just half of the pairs.
When all the keys are symbols, then there is a shorthand syntax which can be used:
$ produce = {apples: 3, oranges: 1, carrots: 12}
$ puts "There are #{produce[:oranges]} oranges in the fridge."
Notice that the keys end with a colon rather than beginning with one, even though these are symbols.
Let's write a method for PersonalChef
that uses and manipulates a hash:
def inventory
produce = {apples: 3, oranges: 1, carrots: 12}
produce.each do |item, quantity|
puts "There are #{quantity} #{item} in the fridge."
end
end
That walks through each of the pairs in the inventory, puts the key into the variable item
and the value into the variable quantity
, then prints them out.
To see this code, load personal_chef.rb
, instantiate Frank, and then run:
$ frank.inventory
Conditional statements evaluate to true
or false
. The most common conditional operators are ==
(equal), >
(greater than), >=
(greater than or equal to), <
(less than), and <=
(less than or equal to).
Some objects also have methods which return a true
or false
, so they're used in conditional statements. For example every object has the method .nil?
which is true
only when the object is nil
. Arrays have a method named .include?
which returns true if the array includes the specified element. The convention in Ruby is that a method which returns true
or false
should have a name ending in a ?
.
Why do we have conditional statements? Most often it's to control conditional instructions, especially if
/elsif
/else
structures. Let's write an example by adding a method to our PersonalChef
class:
def water_status(minutes)
if minutes < 7
puts "The water is not boiling yet."
elsif minutes == 7
puts "It's just barely boiling"
elsif minutes == 8
puts "It's boiling!"
else
puts "Hot! Hot! Hot!"
end
return self
end
Use load
to re-read the file, then try this example using 5
, 7
, 8
and 9
for the values of minutes
.
When the minutes
is 5, here is how the execution goes: "Is it true
that 5 is less than 7? Yes, it is, so print out the line The water is not boiling yet.
".
When the minutes
is 7, it goes like this: "Is it true
that 7 is less than 7? No. Next, is it true
that 7 is equal to 7? Yes, it is, so print out the line It's just barely boiling
".
When the minutes
is 8, it goes like this: "Is it true
that 8 is less than 7? No. Next, is it true
that 8 is equal to 7? No. Next, is it true
that 8 is equal to 8? Yes, it is, so print out the line It's boiling!
".
Lastly, when total is 9, it goes: "Is it true
that 9 is less than 7? No. Next, is it true
that 9 is equal to 7? No. Next, is it true
that 9 is equal to 8? No. Since none of those are true, execute the else
and print the line Hot! Hot! Hot!
.
An if
block has...
- One
if
statement whose instructions are executed only if the statement is true - Zero or more
elsif
statements whose instructions are executed only if the statement is true - Zero or one
else
statement whose instructions are executed if noif
norelsif
statements were true
Only one section of the if
/elsif
/else
structure can have its instructions run. If the if
is true
, for instance, Ruby will never look at the elsif
. Once one block executes, that's it.
We can also repeat a set of instructions based on the truth of a conditional statement. Try out this example by adding it to your personal_chef.rb
:
def countdown(counter)
while counter > 0
puts "The counter is #{counter}"
counter = counter - 1
end
return self
end
See how that works? The counter
starts out as whatever parameter we pass in. The while
instruction evaluates the conditional statement counter > 0
and finds that yes, the counter is greater than zero. Since the condition is true
, execute the instructions inside the loop. First print out "The counter is #{counter}"
then take the value of counter
, subtract one from it, and store it back into counter
. Then the loop goes back to the while
statement. Is it still true
? If so, print the line and subtract one again. Keep repeating until the condition is false
.
I most often use while
, but you can achieve the same results using until
as well. Try this...
def countdown(counter)
until counter == 0
puts "The counter is #{counter}"
counter = counter - 1
end
return self
end
The #1 mistake people encounter when writing conditional statements is the difference between =
and ==
.
-
=
is an assignment. It means "take what's on the right side and stick it into whatever is on the left side" -- it's telling, not asking -
==
is a question. It means "is the thing on the right equal to the thing on the left?" -- it's asking, not telling
You can also combine conditional statements using logical operators. The most common are known as "logical and" and "logical or". In Ruby you can write a "logical and" with double ampersands like this: &&
. You can write a "logical or" with double pipes like this: ||
.
What is nothingness? Is there nothingness only in outer space? Really, when we think of "nothing", isn't it just the absence of something? OK, that's too much philosophy...
nil
is Ruby's way of referring to "nothingness."
If you have three eggs, eat three eggs, then you might think you have "nothing", but in terms of eggs you have "0". Zero is something, it's a number, and it's not nothing.
If you're working with words and have a string like "hello" then delete the "h", "e", "l"s, and "o" you might think you'd end up with nothing, but you really have "" which is an empty string. It's still something.
nil
is Ruby's idea of nothingness. It's usually encountered when you ask for something that doesn't exist. When looking at arrays, for instance, we created a list with five elements then asked Ruby to give us the sixth element of that list. There is no sixth element, so Ruby gave us nil
. It isn't that there's a blank in that sixth spot (""
), it's not a number 0
, it's nothingness -- nil
.
A large percentage of the errors you encounter while writing Ruby code will involve nil
. You thought something was there, you tried to do something to it, and you can't do something to nothing so Ruby creates an error. Let's rewrite our make_toast
method to illustrate nil
:
def make_toast(color)
if color.nil?
puts "How am I supposed to make nothingness toast?"
else
puts "Making your toast #{color}!"
end
return self
end
Reload the file, call frank.make_toast("light brown")
then try frank.make_toast(nil)
. The only method we can rely on nil
executing is .nil?
, pretty much anything else will create an error.
Alright, that's a quick introduction to the language. Now you're ready to dive into your Ruby!
Thanks man , you know i was from a node background and wanted something as fast as clark to take me to know some ruby for my rails project