3. The Oath
“I do solemnly swear:
I will not consider this an exhaustive Ruby lesson
and I will study Ruby more as I progress in Rails,
so James will not come take my keyboard away!”
7. The REPL
Ruby comes with a Read-Eval-Print-Loop tool called irb
In short, you feed it some Ruby and it prints results
8. The REPL
Ruby comes with a Read-Eval-Print-Loop tool called irb
In short, you feed it some Ruby and it prints results
This is an excellent way to learn the language
9. The REPL
Ruby comes with a Read-Eval-Print-Loop tool called irb
In short, you feed it some Ruby and it prints results
This is an excellent way to learn the language
It becomes a powerful data management tool when
used with Rails
10. The REPL
Ruby comes with a Read-Eval-Print-Loop tool called irb
In short, you feed it some Ruby and it prints results
This is an excellent way to learn the language
It becomes a powerful data management tool when
used with Rails
Do yourself a favor and start playing with irb a lot
13. Using irb
Run irb to launch it
$ irb
>> 1 + 2
=> 3
>> "james".capitalize
=> "James"
>> %w[y b u R].reverse
=> ["R", "u", "b", "y"]
>> _.join("-")
=> "R-u-b-y"
>> exit
14. Using irb
Run irb to launch it
$ irb
You enter Ruby >> 1 + 2
expressions => 3
>> "james".capitalize
=> "James"
>> %w[y b u R].reverse
=> ["R", "u", "b", "y"]
>> _.join("-")
=> "R-u-b-y"
>> exit
15. Using irb
Run irb to launch it
$ irb
You enter Ruby >> 1 + 2
expressions => 3
>> "james".capitalize
=> "James"
irb responds with the >> %w[y b u R].reverse
results as you type => ["R", "u", "b", "y"]
>> _.join("-")
=> "R-u-b-y"
>> exit
16. Using irb
Run irb to launch it
$ irb
You enter Ruby >> 1 + 2
expressions => 3
>> "james".capitalize
=> "James"
irb responds with the >> %w[y b u R].reverse
results as you type => ["R", "u", "b", "y"]
>> _.join("-")
=> "R-u-b-y"
_ holds the last result >> exit
17. Using irb
Run irb to launch it
$ irb
You enter Ruby >> 1 + 2
expressions => 3
>> "james".capitalize
=> "James"
irb responds with the >> %w[y b u R].reverse
results as you type => ["R", "u", "b", "y"]
>> _.join("-")
=> "R-u-b-y"
_ holds the last result >> exit
Use exit() to quit
20. Data Types and Structures
Ruby has data types common to most programming
languages: String, Integer, Float, …
21. Data Types and Structures
Ruby has data types common to most programming
languages: String, Integer, Float, …
Ruby has two primary data structures: Array and Hash
22. Data Types and Structures
Ruby has data types common to most programming
languages: String, Integer, Float, …
Ruby has two primary data structures: Array and Hash
These structures are very versatile and can serve as
sets, queues, stacks, …
23. Data Types and Structures
Ruby has data types common to most programming
languages: String, Integer, Float, …
Ruby has two primary data structures: Array and Hash
These structures are very versatile and can serve as
sets, queues, stacks, …
Ruby has some other data types, like Time
24. Data Types and Structures
Ruby has data types common to most programming
languages: String, Integer, Float, …
Ruby has two primary data structures: Array and Hash
These structures are very versatile and can serve as
sets, queues, stacks, …
Ruby has some other data types, like Time
All of the above are full objects in Ruby
26. String “ta lot of escapesn#{1 + 2}” ‘less ( or ’)’
255 0377
Integer
0xFF 0b11111111
0.00003
Float
3.0e-5
[“James”, “Edward”, “Gray”, “II”]
Array
%w[James Edward Gray II]
Hash {“name” => “James”, “age” => 33}
Symbol :first_name
Regexp /AJ(?:ames )?E(?:dward )?G(?:ray )?(?:II|2)z/
Time.now
Time
Time.local(2010, 3, 10) Time.utc(2010, 3, 10)
27. String “ta lot of escapesn#{1 + 2}” ‘less ( or ’)’
255 0377
Integer
0xFF 0b11111111
0.00003
Float
3.0e-5
[“James”, “Edward”, “Gray”, “II”]
Array
%w[James Edward Gray II]
Hash {“name” => “James”, “age” => 33}
Symbol :first_name
Regexp /AJ(?:ames )?E(?:dward )?G(?:ray )?(?:II|2)z/
Time.now
Time
Time.local(2010, 3, 10) Time.utc(2010, 3, 10)
28. String “ta lot of escapesn#{1 + 2}” ‘less ( or ’)’
255 0377
Integer
0xFF 0b11111111
0.00003
Float
3.0e-5
[“James”, “Edward”, “Gray”, “II”]
Array
%w[James Edward Gray II]
Hash {“name” => “James”, “age” => 33}
Symbol :first_name
Regexp /AJ(?:ames )?E(?:dward )?G(?:ray )?(?:II|2)z/
Time.now
Time
Time.local(2010, 3, 10) Time.utc(2010, 3, 10)
29. String “ta lot of escapesn#{1 + 2}” ‘less ( or ’)’
255 0377
Integer
0xFF 0b11111111
0.00003
Float
3.0e-5
[“James”, “Edward”, “Gray”, “II”]
Array
%w[James Edward Gray II]
Hash {“name” => “James”, “age” => 33}
Symbol :first_name
Regexp /AJ(?:ames )?E(?:dward )?G(?:ray )?(?:II|2)z/
Time.now
Time
Time.local(2010, 3, 10) Time.utc(2010, 3, 10)
30. String “ta lot of escapesn#{1 + 2}” ‘less ( or ’)’
255 0377
Integer
0xFF 0b11111111
0.00003
Float
3.0e-5
[“James”, “Edward”, “Gray”, “II”]
Array
%w[James Edward Gray II]
Hash {“name” => “James”, “age” => 33}
Symbol :first_name
Regexp /AJ(?:ames )?E(?:dward )?G(?:ray )?(?:II|2)z/
Time.now
Time
Time.local(2010, 3, 10) Time.utc(2010, 3, 10)
31. String “ta lot of escapesn#{1 + 2}” ‘less ( or ’)’
255 0377
Integer
0xFF 0b11111111
0.00003
Float
3.0e-5
[“James”, “Edward”, “Gray”, “II”]
Array
%w[James Edward Gray II]
Hash {“name” => “James”, “age” => 33}
Symbol :first_name
Regexp /AJ(?:ames )?E(?:dward )?G(?:ray )?(?:II|2)z/
Time.now
Time
Time.local(2010, 3, 10) Time.utc(2010, 3, 10)
32. String “ta lot of escapesn#{1 + 2}” ‘less ( or ’)’
255 0377
Integer
0xFF 0b11111111
0.00003
Float
3.0e-5
[“James”, “Edward”, “Gray”, “II”]
Array
%w[James Edward Gray II]
Hash {“name” => “James”, “age” => 33}
Symbol :first_name
Regexp /AJ(?:ames )?E(?:dward )?G(?:ray )?(?:II|2)z/
Time.now
Time
Time.local(2010, 3, 10) Time.utc(2010, 3, 10)
33. String “ta lot of escapesn#{1 + 2}” ‘less ( or ’)’
255 0377
Integer
0xFF 0b11111111
0.00003
Float
3.0e-5
[“James”, “Edward”, “Gray”, “II”]
Array
%w[James Edward Gray II]
Hash {“name” => “James”, “age” => 33}
Symbol :first_name
Regexp /AJ(?:ames )?E(?:dward )?G(?:ray )?(?:II|2)z/
Time.now
Time
Time.local(2010, 3, 10) Time.utc(2010, 3, 10)
67. The if statement
num = rand(10)
print "#{num}: "
if num == 7
puts "Lucky!"
elsif num <= 3
puts "A little low."
else
puts "A boring number."
end
# >> 2: A little low.
68. The if statement
Ruby has if/elsif/else
conditionals num = rand(10)
print "#{num}: "
if num == 7
puts "Lucky!"
elsif num <= 3
puts "A little low."
else
puts "A boring number."
end
# >> 2: A little low.
69. The if statement
Ruby has if/elsif/else
conditionals num = rand(10)
print "#{num}: "
The code is run if the if num == 7
puts "Lucky!"
condition is true elsif num <= 3
puts "A little low."
else
puts "A boring number."
end
# >> 2: A little low.
70. The if statement
Ruby has if/elsif/else
conditionals num = rand(10)
print "#{num}: "
The code is run if the if num == 7
puts "Lucky!"
condition is true elsif num <= 3
puts "A little low."
In Ruby, false and nil else
puts "A boring number."
are false and all other end
# >> 2: A little low.
objects are true (0, “”,
etc.)
71. The if statement
Ruby has if/elsif/else
conditionals num = rand(10)
print "#{num}: "
The code is run if the if num == 7
puts "Lucky!"
condition is true elsif num <= 3
puts "A little low."
In Ruby, false and nil else
puts "A boring number."
are false and all other end
# >> 2: A little low.
objects are true (0, “”,
etc.)
73. When Things go Wrong
>> 42 / 0
ZeroDivisionError: divided by 0
from (irb):1:in `/'
from (irb):1
from :0
74. When Things go Wrong
Ruby “raises” errors
(called Exceptions)
when things go wrong
>> 42 / 0
ZeroDivisionError: divided by 0
from (irb):1:in `/'
from (irb):1
from :0
75. When Things go Wrong
Ruby “raises” errors
(called Exceptions)
when things go wrong
Error objects have a >> 42 / 0
ZeroDivisionError: divided by 0
type, message, and from (irb):1:in `/'
from (irb):1
backtrace from :0
76. When Things go Wrong
Ruby “raises” errors
(called Exceptions)
when things go wrong
Error objects have a >> 42 / 0
ZeroDivisionError: divided by 0
type, message, and from (irb):1:in `/'
from (irb):1
backtrace from :0
77. When Things go Wrong
Ruby “raises” errors
(called Exceptions)
when things go wrong
Error objects have a >> 42 / 0
ZeroDivisionError: divided by 0
type, message, and from (irb):1:in `/'
from (irb):1
backtrace from :0
78. When Things go Wrong
Ruby “raises” errors
(called Exceptions)
when things go wrong
Error objects have a >> 42 / 0
ZeroDivisionError: divided by 0
type, message, and from (irb):1:in `/'
from (irb):1
backtrace from :0
By default, processing
stops if the error isn’t
“rescued”
80. Exception Handling
>> begin
>> n = 42 / 0
>> rescue ZeroDivisionError => error
>> n=0
>> end
=> 0
>> n
=> 0
81. Exception Handling
Put code that might
raise errors between >> begin
>> n = 42 / 0
begin … end >>
>>
rescue ZeroDivisionError => error
n=0
>> end
=> 0
>> n
=> 0
82. Exception Handling
Put code that might
raise errors between >> begin
>> n = 42 / 0
begin … end >>
>>
rescue ZeroDivisionError => error
n=0
>> end
Add rescue clauses =>
>>
0
n
for the error types you => 0
want to handle
85. Everything is an Object
>> -42.abs
=> 42
>> 3.times { puts "Howdy" }
Howdy
Howdy
Howdy
=> 3
86. Everything is an Object
With a few very minor
exceptions, everything >> -42.abs
=> 42
in Ruby is an Object >> 3.times { puts "Howdy" }
Howdy
Howdy
Howdy
=> 3
87. Everything is an Object
With a few very minor
exceptions, everything >> -42.abs
=> 42
in Ruby is an Object >> 3.times { puts "Howdy" }
Howdy
Howdy
Even a number literal is Howdy
an Object and you can => 3
call methods on it
89. class Name
def initialize(first = nil)
self.first = first
end
def first=(first)
@first = first
end
def first
@first
end
end
Instance Variables
Private, per object storage
90. class Name
def initialize(first = nil)
self.first = first
end
def first=(first)
@first = first
end
def first
@first
end
end
Instance Variables
Private, per object storage
91. class Name
def initialize(first = nil)
self.first = first
end
def first=(first)
@first = first
end
def first
@first
end
end
Instance Variables
Private, per object storage
92. class Name
def initialize(first = nil)
self.first = first
end
def first=(first)
@first = first
end
def first
@first
end
end
Instance Variables
Private, per object storage
93. class Name
def initialize(first = nil)
self.first = first
end
def first=(first)
@first = first
end
def first
@first
end
end
Instance Variables
Private, per object storage
94. class Name
def initialize(first = nil)
self.first = first
end
def first=(first)
@first = first
end
def first
@first
end
end
Instance Variables
Private, per object storage
95. class Name
def initialize(first = nil)
self.first = first
end dana = Name.new("Dana")
james = Name.new
def first=(first) james.first = "James"
@first = first puts dana.first
end puts james.first
# >> Dana
def first # >> James
@first
end
end
Instance Variables
Private, per object storage
96. class Name
def initialize(first = nil)
self.first = first
end dana = Name.new("Dana")
james = Name.new
def first=(first) james.first = "James"
@first = first puts dana.first
end puts james.first
# >> Dana
def first # >> James
@first
end
end
Instance Variables
Private, per object storage
97. class Name
def initialize(first = nil)
self.first = first
end dana = Name.new("Dana")
james = Name.new
def first=(first) james.first = "James"
@first = first puts dana.first
end puts james.first
# >> Dana
def first # >> James
@first
end
end
Instance Variables
Private, per object storage
98. class Name
def initialize(first = nil)
self.first = first
end dana = Name.new("Dana")
james = Name.new
def first=(first) james.first = "James"
@first = first puts dana.first
end puts james.first
# >> Dana
def first # >> James
@first
end
end
Instance Variables
Private, per object storage
100. Single Inheritance
class Parent
def greet
@greeting ||= "Hello!"
end
end
class Child < Parent
def initialize
@greeting = "Yo!"
end
end
puts Parent.new.greet
puts Child.new.greet
# >> Hello!
# >> Yo!
101. Single Inheritance
A Class can declare class Parent
def greet
one parent @greeting ||= "Hello!"
end
end
class Child < Parent
def initialize
@greeting = "Yo!"
end
end
puts Parent.new.greet
puts Child.new.greet
# >> Hello!
# >> Yo!
102. Single Inheritance
A Class can declare class Parent
def greet
one parent @greeting ||= "Hello!"
end
A child inherits all end
class Child < Parent
behavior from all def initialize
@greeting = "Yo!"
ancestors end
end
puts Parent.new.greet
puts Child.new.greet
# >> Hello!
# >> Yo!
103. Single Inheritance
A Class can declare class Parent
def greet
one parent @greeting ||= "Hello!"
end
A child inherits all end
class Child < Parent
behavior from all def initialize
@greeting = "Yo!"
ancestors end
end
Ruby’s Object is the puts Parent.new.greet
puts Child.new.greet
highest parent for all # >> Hello!
Classes # >> Yo!
105. Questions and
Dangerous Methods
>> 0.zero?
=> true
>> 0.0.zero?
=> true
>> 0.00001.zero?
=> false
>> s = "string"
=> "string"
>> s.upcase
=> "STRING"
>> s
=> "string"
>> s.upcase!
=> "STRING"
>> s
=> "STRING"
106. Questions and
Dangerous Methods
Ruby has some >>
=>
0.zero?
true
method name >>
=>
0.0.zero?
true
conventions >>
=>
0.00001.zero?
false
>> s = "string"
=> "string"
>> s.upcase
=> "STRING"
>> s
=> "string"
>> s.upcase!
=> "STRING"
>> s
=> "STRING"
107. Questions and
Dangerous Methods
Ruby has some >>
=>
0.zero?
true
method name >>
=>
0.0.zero?
true
conventions >>
=>
0.00001.zero?
false
Question methods >>
=>
s = "string"
"string"
(answering true or >> s.upcase
=> "STRING"
false) end in ? >> s
=> "string"
>> s.upcase!
=> "STRING"
>> s
=> "STRING"
108. Questions and
Dangerous Methods
Ruby has some >>
=>
0.zero?
true
method name >>
=>
0.0.zero?
true
conventions >>
=>
0.00001.zero?
false
Question methods >>
=>
s = "string"
"string"
(answering true or >> s.upcase
=> "STRING"
false) end in ? >> s
=> "string"
>> s.upcase!
Dangerous methods => "STRING"
>> s
end in ! => "STRING"
111. Modules
module Netstring
def to_netstring(*args)
str = to_s(*args)
"#{str.length}:#{str},"
end
end
class String
include Netstring
end
class Integer < Numeric
include Netstring
end
p "James".to_netstring
p 42.to_netstring(2)
# >> "5:James,"
# >> "6:101010,"
112. Modules
module Netstring
def to_netstring(*args)
Ruby doesn’t have str = to_s(*args)
"#{str.length}:#{str},"
multiple inheritance end
end
class String
include Netstring
end
class Integer < Numeric
include Netstring
end
p "James".to_netstring
p 42.to_netstring(2)
# >> "5:James,"
# >> "6:101010,"
113. Modules
module Netstring
def to_netstring(*args)
Ruby doesn’t have str = to_s(*args)
"#{str.length}:#{str},"
multiple inheritance end
end
Instead, we can “mix” a class String
include Netstring
Module of methods end
“in”to a Class class Integer < Numeric
include Netstring
end
p "James".to_netstring
p 42.to_netstring(2)
# >> "5:James,"
# >> "6:101010,"
114. Modules
module Netstring
def to_netstring(*args)
Ruby doesn’t have str = to_s(*args)
"#{str.length}:#{str},"
multiple inheritance end
end
Instead, we can “mix” a class String
include Netstring
Module of methods end
“in”to a Class class Integer < Numeric
include Netstring
end
We call these p "James".to_netstring
Modules “mixins” p
#
42.to_netstring(2)
>> "5:James,"
# >> "6:101010,"
115. Modules
module Netstring
def to_netstring(*args)
Ruby doesn’t have str = to_s(*args)
"#{str.length}:#{str},"
multiple inheritance end
end
Instead, we can “mix” a class String
include Netstring
Module of methods end
“in”to a Class class Integer < Numeric
include Netstring
end
We call these p "James".to_netstring
Modules “mixins” p
#
42.to_netstring(2)
>> "5:James,"
# >> "6:101010,"
118. Blocks
def until_successful
loop do
break if yield == :success
end
end
until_successful {
puts "Called."
:success if rand(3).zero?
}
# >> Called.
# >> Called.
# >> Called.
# >> Called.
119. Blocks
In Ruby, you can pass def until_successful
a block (some code) to loop do
break if yield == :success
a called method end
end
until_successful {
puts "Called."
:success if rand(3).zero?
}
# >> Called.
# >> Called.
# >> Called.
# >> Called.
120. Blocks
In Ruby, you can pass def until_successful
a block (some code) to loop do
break if yield == :success
a called method end
end
Block code is in until_successful {
puts "Called."
{ … } or do … end :success if rand(3).zero?
}
# >> Called.
# >> Called.
# >> Called.
# >> Called.
121. Blocks
In Ruby, you can pass def until_successful
a block (some code) to loop do
break if yield == :success
a called method end
end
Block code is in until_successful {
puts "Called."
{ … } or do … end :success if rand(3).zero?
}
That method can run # >> Called.
# >> Called.
the passed code with # >> Called.
# >> Called.
yield
126. The each() Iterator
name = %w[James Edward Gray II]
name.each do |word|
puts word.reverse
end
# >> semaJ
# >> drawdE
# >> yarG
# >> II
127. The each() Iterator
Let Ruby manage name = %w[James Edward Gray II]
indexes for you name.each do |word|
puts word.reverse
end
# >> semaJ
# >> drawdE
# >> yarG
# >> II
128. The each() Iterator
Let Ruby manage name = %w[James Edward Gray II]
indexes for you name.each do |word|
puts word.reverse
end
each() will call the # >> semaJ
# >> drawdE
block once with every # >> yarG
# >> II
item of the collection
130. The map() Iterator
nums = *1..5
p nums
p nums.map { |n| n ** 2 }
# >> [1, 2, 3, 4, 5]
# >> [1, 4, 9, 16, 25]
131. The map() Iterator
map() is used to
transform your
collection
nums = *1..5
p nums
p nums.map { |n| n ** 2 }
# >> [1, 2, 3, 4, 5]
# >> [1, 4, 9, 16, 25]
132. The map() Iterator
map() is used to
transform your
collection
nums = *1..5
Each item of the p nums
p nums.map { |n| n ** 2 }
collection is passed # >> [1, 2, 3, 4, 5]
into the block and the # >> [1, 4, 9, 16, 25]
result of the block
replaces that item in a
new collection
133. The map() Iterator
map() is used to
transform your
collection
nums = *1..5
Each item of the p nums
p nums.map { |n| n ** 2 }
collection is passed # >> [1, 2, 3, 4, 5]
into the block and the # >> [1, 4, 9, 16, 25]
result of the block
replaces that item in a
new collection
135. The select() Iterator
nums = *1..10
p nums
p nums.select { |n| n % 2 == 0 }
# >> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# >> [2, 4, 6, 8, 10]
136. The select() Iterator
select() can be used
to filter a collection
nums = *1..10
p nums
p nums.select { |n| n % 2 == 0 }
# >> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# >> [2, 4, 6, 8, 10]
137. The select() Iterator
select() can be used
to filter a collection
Each item is passed nums = *1..10
into the block and if the p nums
p nums.select { |n| n % 2 == 0 }
# >> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
block conditional # >> [2, 4, 6, 8, 10]
evaluates to a true
value the item is placed
in the new collection
138. The select() Iterator
select() can be used
to filter a collection
Each item is passed nums = *1..10
into the block and if the p nums
p nums.select { |n| n % 2 == 0 }
# >> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
block conditional # >> [2, 4, 6, 8, 10]
evaluates to a true
value the item is placed
in the new collection
139. And Much, Much More!
I have barely scratched the surface of Ruby
141. Ruby is a Rich Language
Over 140 methods on String and over 70 on Array
142. Ruby is a Rich Language
Over 140 methods on String and over 70 on Array
Automatic “big math” conversions
143. Ruby is a Rich Language
Over 140 methods on String and over 70 on Array
Automatic “big math” conversions
A very capable case statement (multi-branch conditional)
144. Ruby is a Rich Language
Over 140 methods on String and over 70 on Array
Automatic “big math” conversions
A very capable case statement (multi-branch conditional)
Custom per object behaviors
145. Ruby is a Rich Language
Over 140 methods on String and over 70 on Array
Automatic “big math” conversions
A very capable case statement (multi-branch conditional)
Custom per object behaviors
Over 30 iterators
146. Ruby is a Rich Language
Over 140 methods on String and over 70 on Array
Automatic “big math” conversions
A very capable case statement (multi-branch conditional)
Custom per object behaviors
Over 30 iterators
Powerful reflection capabilities