class
keyword to define a class
class Pokemon
...
end
new
method constructs/instantiates an object
new
method will be defined on the class already
new
will call the
initialize
method
initialize
takes whatever parameters you want
class Pokemon
def initialize(trainer, level = 5)
...
end
end
pikachu = Pokemon.new(ash, 7)
staryu = Pokemon.new(misty)
def
as always
self
keyword refers to the calling object
class Pokemon
def initialize(trainer, level = 5)
...
end
def lose_health(damage)
...
end
def attack(other)
other.lose_health(100)
end
end
pikachu.attack(staryu)
class Pokemon
def initialize(trainer, level = 5)
@trainer = trainer
@level = level
@health = 100
end
def lose_health(damage)
@health -= 100
end
def attack(other)
other.lose_health(100)
end
end
pikachu.attack(staryu)
class Pokemon
...
def health
@health
end
def health=(value)
@health = value
end
end
pikachu.health = 400
puts pikachu.health
attr_accessor
attr_reader
defines getters
attr_writer
defines setters
attr_accessor
defines both
class Pokemon
attr_accessor :health, :trainer, :level
...
end
irb> dog = Dog.new
irb> dog.bark
"Woof"
irb> dog.send :bark
"Woof"
irb> message = :bark
irb> dog.send message
"Woof"
times
method defined on numbers
class
method on any object to get its class
# Using the #constantize method defined in ActiveSupport in Rails
pokemon = "Pokemon".constantize.new
class Pokemon
def self.known?(species)
...
end
end
Pokemon.known? :pikachu
As a side note, Class not only has #new defined but ::new as well
my_class = Class.new do
def foo
"bar"
end
...
end
superclass
method returns parent class
class Pikachu < Pokemon
...
end
class Pokemon
def initialize
@health = initial_health
end
end
class Pikachu < Pokemon
def initial_health
200 * level
end
end
collection = ...
collection.each do |element|
# We don't know what type of collection we are dealing with
# But we don't care because we assume #each will iterate over the elements
...
end
class Iterable
# Abstract #each method
def map
results = []
self.each do |element|
results << yield element
end
results
end
def filter
results = []
self.each do |element|
results << element if yield element
end
results
end
def reduce(initial)
self.each do |element|
initial = yield initial, element
end
initial
end
end
Despite being correct, there is no good way to reuse this functionality in classes that have a more logical parent class
module Enumerable
def map
...
end
def filter
...
end
def reduce
...
end
end
class CollectionOfSomeSort
include Enumerable
def each
...
end
end
collection = CollectionOfSomeSort.new
collection.map { |element| [element, element] }
Well, we can do just that
class String
def pluralize
if self =~ /s$/
self
else
self + "s"
end
end
end
Use this only if you have a very good reason