A scope is where you can refer to a variable. A block defines a block scope. A variable defined inside a block will be defined only inside that block and you can't reference it after the end of block. The scope of a local-variable declaration is from the point at which the declaration appears to the end of that block.
This is a great explanation of the difference between scope and block.
Block parameters are always scoped local to the block. The variable item is created on the first line of the loop and exists only inside the loop.
The following code will cause the error "undefined local variable or method item".
(1..5).each do |item|
item = item + 1
end
puts item
Block parameters are always scoped local to the block.
In this example the variable current created before the loop. In the first line of the loop another variable called current is created and exists only inside the loop. It will not change the variable outside of the loop. It will puts 2019.
current = 2019
(1..10).each do |current|
current = current + 1
end
puts current
The variable name is created outside of the loop and changed inside of the loop.
name = "Bob"
counter = 0
('Ted'..'Zed').each do |n|
name = n
end
puts name
The variable name is created outside of the if and changed inside of the if with a true condition.
name = "Ted"
if true
name = "Bob"
end
puts name
The variable name is created outside of the if and NOT changed inside of the if with a false condition.
name = "Ted"
if false
name = "Bob"
end
puts name
Methods that act on the data (like drive and is_vintage) are inside the class and hide the implementation.
require 'date'
class Car
def initialize(make, year, mileage, color)
@make = make
@year = year
@mileage = mileage
@color = color
end
def drive(distance)
@mileage += distance
end
def is_vintage?()
if (Date.today.year - @year > 30)
return true
end
return false
end
def description()
return "Make: #{@make}, Year: #{@year}, Mileage: #{@mileage}, Vintage: #{is_vintage?()}"
end
end
We use .new to create an instance of a class.
work_car = Car.new('Toyota', 2018, 5000)
When we create an instance we can call instance methods on it.
work_car = Car.new('Toyota', 2018, 5000)
puts ("The work car is #{work_car.description()}")
work_car.drive(100)
puts ("The work car is #{work_car.description()}")
A getter simply returns the instance variable we want to read.
class Hamburger
def initialize(patty, bun)
@patty = patty
@bun = bun
end
def get_patty()
return @patty
end
def get_bun()
return @bun
end
def to_string()
"#{@patty} patty on a #{@bun} bun"
end
end
hamburger1 = Hamburger.new('beef', 'brioche')
puts (hamburger1.to_string())
puts ("This burger contains #{hamburger1.get_patty()}")
Accessors prevent us from having to define getter methods.
class Hamburger
attr_reader(:patty, :bun)
def initialize(patty, bun)
@patty = patty
@bun = bun
end
def to_string()
"#{@patty} patty on a #{@bun} bun"
end
end
hamburger1 = Hamburger.new('beef', 'brioche')
puts (hamburger1.to_string())
puts ("This burgger contains #{hamburger1.patty}")
puts hamburger1.bun