Ruby the Hard Way: Designing and Debugging

Rules for If-statements

  • mandatory else-statement
  • if else-statment never runs, because it doesnt make sense, there need to be a die function, that prints out an error message and closes afterwards
  • Don’t nest if-statements more than 2 deep
  • Treat if-statements like paragraphs, where each if-elsif-else grouping is like a set of sentences. Put blank lines before and after.
  • Your boolean tests should be simple. If they are complex, move their calculations to variables earlier in your function and use a good name for the variable.


While-loop for never ending loop => rarely used

For-loop for looping a few times => better choice most of the time



Symbol Review




table 2: “Learn Ruby the Hard Way”

Keyword Description Example
BEGIN Run this block when the script starts. BEGIN { puts "hi" }
END Run this block when the script is done. END { puts "hi" }
alias Create another name for a function. alias X Y
and Logical and, but lower priority than &&. puts "Hello" and "Goodbye"
begin Start a block, usually for exceptions. begin end
break Break out of a loop right now. while true; break; end
case Case style conditional, like an if. case X; when Y; else; end
class Define a new class. class X; end
def Define a new function. def X(); end
defined? Is this class/function/etc. defined already? defined? Class == "constant"
do Create a block that maybe takes a parameter. (0..5).each do |x| puts x end
else Else conditional. if X; else; end
elsif Else if conditional if X; elsif Y; else; end
end Ends blocks, functions, classes, everything. begin end # many others
ensure Run this code whether an exception happens or not. begin ensure end
for For loop syntax. The .each syntax is preferred. for X in Y; end
if If conditional. if X; end
in In part of for-loops. for X in Y; end
module Define a new module. module X; end
next Skip to the next element of a .each iterator. (0..5).each {|y| next }
not Logical not. But use ! instead. not true == false
or Logical or. puts "Hello" or "Goodbye"
redo Rerun a code block exactly the same. (0..5).each {|i| redo if i > 2}
rescue Run this code if an exception happens. begin rescue X; end
retry In a rescue clause, says to try the block again. (0..5).each {|i| retry if i > 2}
return Returns a value from a function. Mostly optional. return X
self The current object, class, or module. defined? self == "self"
super The parent class of this class. super
then Can be used with if optionally. if true then puts "hi" end
undef Remove a function definition from a class. undef X
unless Inverse of if. unless false then puts "not" end
until Inverse of while, execute block as long as false. until false; end
when Part of case conditionals. case X; when Y; else; end
while While loop. while true; end
yield Pause and transfer control to the code block. yield


Data Types


table 3: “Learn Ruby the Hard Way”

Type Description Example
true True boolean value. true or false == true
false False boolean value. false and true == false
nil Represents “nothing” or “no value”. x = nil
strings Stores textual information. x = "hello"
numbers Stores integers. i = 100
floats Stores decimals. i = 10.389
arrays Stores a list of things. j = [1,2,3,4]
hashes Stores a key=value mapping of things. e = {'x' => 1, 'y' => 2}

String Escape Sequences


table 4: “Learn Ruby the Hard Way”

Escape Description
\\ Backslash
\' Single-quote
\" Double-quote
\a Bell
\b Backspace
\f Formfeed
\n Newline
\r Carriage
\t Tab
\v Vertical tab



table 5: “Learn Ruby the Hard Way”

+ Add 2 + 4 == 6
- Subtract 2 - 4 == -2
* Multiply 2 * 4 == 8
** Power of 2 ** 4 == 16
/ Divide 2 / 4.0 == 0.5
% Modulus 2 % 4 == 2
> Greater than 4 > 4 == false
. Dot access "1".to_i == 1
:: Colon access Module::Class
[] List brackets [1,2,3,4]
! Not !true == false
< Less than 4 < 4 == false
> Greater than 4 < 4 == false
>= Greater than equal 4 >= 4 == true
<= Less than equal 4 <= 4 == true
<=> Comparison 4 <=> 4 == 0
== Equal 4 == 4 == true
=== Equality 4 === 4 == true
!= Not equal 4 != 4 == false
&& Logical and (higher precedence) true && false == false
|| Logical or (higher precedence) true || false == true
.. Range inclusive (0..3).to_a == [0, 1, 2, 3]
... Range non-inclusive (0...3).to_a == [0, 1, 2]
@ Object scope @var ; @@classvar
@@ Class scope @var ; @@classvar
$ Global scope $stdin




Doing things to Arrays


ten_things = "Apples Oranges Crows Telephone Light Sugar"

puts "Wait there are not ten things in that list. Let's fix that"

stuff = ten_things.split(' ') #splits string by SPACE
more_stuff = ["Day", "Night", "Song", "Frisbee", "Corn", "Banana", "Girl", "Boy"]

# using math to make sure there's 10 items

while stuff.length != 10     #while there are not 10 things in stuff array do:
 next_one = more_stuff.pop      #.pop takes the last thing from array
 puts "Adding: #{next_one}" 
 stuff.push(next_one)           #adding elements to stuff array
 puts "There are #{stuff.length} items now."

puts "There we go: #{stuff}"

puts "Let's do some things with stuff."

puts stuff[1]        #puts whats in array stuff at position 2
puts stuff[-1]       #puts what is last in array
puts stuff.pop()     #same as above
puts stuff.join(' ')      #add SPACE between elements in stuff array
puts stuff[3..5].join("#")  #add what's on position 4 and 6 and also add
                             '#' between elements

Hashes, Oh Lovely Hashes


A Hash:

Let’s us store all kinds of stuff. It can store data and organize them. It functions like a list or database. We can access stuff from Hashes not only with numbers like we do with arrays. They have “keys” with “values” attached to them like ‘name’ => ‘Mark’


stuff = {‘name’ => ‘Mark’ , ‘country’ => ‘Germany’ , ‘animals’ => ‘cat’}   #{…}

puts stuff[‘name’]

> Mark

A Hash let’s us use strings as index…


stuff[‘car’] = “Audi”

stuff[‘color’] = “black”

puts stuff

{‘name’ => ‘Mark’ , ‘country’ => ‘Germany’ , ‘animals’ => ‘cat’, ‘car’ => ‘Audi’, ‘color’ => ‘black’}

and we can add stuff to it aswell



> Audi



puts stuff

{‘name’ => ‘Mark’ , ‘country’ => ‘Germany’ , ‘animals’ => ‘cat’}

and also delete it again

# create a mapping of state to abbreviation
states = {
 'Oregon' => 'OR',
 'Florida' => 'FL',
 'California' => 'CA',
 'New York' => 'NY',
 'Michigan' => 'MI'

# create a basic set of states and some cities in them
cities = {
 'CA' => 'San Francisco',
 'MI' => 'Detroit',
 'FL' => 'Jacksonville'

# add some more cities
cities['NY'] = 'New York'
cities['OR'] = 'Portland'

#puts out some cities
puts '-' * 10
puts "Michigan's abbreviation is: #{states['Michigan']}"
puts "Florida's abbreviation is #{states['Florida']}"

# do it by using the state then cities dict
puts '-' * 10
states.each do |state, abbrev|          #for-loop, for every states object call 
                                   each of them and what attribute belongs to them
 puts "#{state} is abbreviated #{abbrev}"

# puts every city in state
puts '-' * 10
cities.each do |abbrev, city| #same as above
 puts "#{abbrev} has the city #{city}"

# now do both at the same time
puts '-' * 10
#by default ruby says "nil" when something isnt in there
state = states['Texas']

if !state                    #because theres no Texas in states puts:
 puts "Sorry, no Texas"

# default values using ||= with the nil result
city = cities['TX']
city ||= 'Does Not Exist'
puts "The city for the state 'TX' is #{city}"

Modules, Classes, and Objects


class Song

def initialize(lyrics)     #inside the class Song define a function and assign a 
 @lyrics = lyrics          variable to this object(@) lyrics

def sing_me_a_song()      #for-loop that puts every line of the Songs array
 @lyrics.each {|line| puts line}

happy_bday =["Happy birthday to you",   #create the Song class and 
 "I dont want to get sued",                       add 3 strings to an array
 "So ill stop right here"])

bulls_on_parade =["They rally around tha family",   #same as above but  
 "With pockets full of shells"])                              assigned to another
happy_bday.sing_me_a_song()    #call the sing_me_a_song function within the Song 

bulls_on_parade.sing_me_a_song() #same as above



  1. A Ruby file with some functions or variables in it inside a module .. end block..
  2. You import that file.
  3. And you can access the functions or variables in that module with the . (dot) operator.



Is a way to take a grouping of functions and data and place them inside a container , that can be accessed by .(dot) operator like with Modules



If you “require” something like for Modules, you “instantiate”(create) an Object. To instantiate an Object , you call the new function for it


What’s happening in the background when creating an Object:

  1. Ruby looks for the class and sees if its defined
  2. then it crafts an empty object with all the functions specified in the class
  3. after that, it looks out for the initialisation function, if found run/initialise it
  4. then with @, tell Ruby i want this specific variable to be part of my object
  5. assign the newly made Object to a variable to work with it later




Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s