Classes and Instances

Ref. WGR Chapter 3, Organizing objects with classes

Example Class

class Cookie
  def sweeten(more_chips = 10)
    @chips ||= 0    # lazy initialization
    @chips += more_chips
  end

  def yummy?
    @chips and @chips >= 20
  end
end

Creating and Using Objects

Constructors

class Cookie
  def initialize
    @chips = 0
  end
end

cookie = Cookie.new  # *not* Cookie.initialize!

Active vs. Lazy Initialization

Active initialization (inside the constructor) leads to simpler code elsewhere in the object, since other methods can assume the instance variables are ready to roll.

Active Initialization

class Cookie
  def initialize
    @chips = 0    # active initialization
  end

  def sweeten(more_chips = 10)
    @chips += more_chips
  end

  def yummy?
    @chips >= 20
  end
end

Lazy Initialization

class Cookie
  def sweeten(more_chips = 10)
    @chips ||= 0    # lazy initialization
    @chips += more_chips
  end

  def yummy?
    @chips and      # defensive coding
      @chips >= 20
  end
end

What does new do?

  1. allocates memory for the instance
  2. calls initialize on the new instance
  3. returns a pointer to the instance

So by the time assignment (=) happens, the object has been constructed and initialized.

So a constructor is your one big chance to initialize everything before anyone else gets a pointer to it.

Instance methods

class Cookie
  def bake
    @temp = 350
  end
end

Instance variables

Getter and setter methods

class Person
  def age=(years_old)
    @age = years_old
  end
  def age
    @age
  end
end

alice = Person.new
alice.age= 17
alice.age #=> 17

alice.@age #=> SyntaxError

Ruby's setter sugar

alice.age = 17

is the same as

alice.age=(17)

The setter gotcha

class Person
  def age=(years_old)
    @age = years_old
  end
  def bar_mitzvah!
    age = 13   # oops
  end
end

The setter gotcha solved

class Person
  def age=(years_old)
    @age = years_old
  end
  def bar_mitzvah!
    @age = 13
  end
  def bat_mitzvah!
    self.age = 13
  end
end

Attributes

Attribute Shortcuts

aka "macros"

class Thing
  attr_reader :age    #  def age; @age; end
  attr_writer :age    #  def age=(x); @age = x; end
  attr_accessor :age  # both of the above
end

Constructor plus Attributes

class Person
  attr_accessor :age
  def initialize
    @age = 20
  end
end

alice = Person.new
alice.age #=> 20

Attribute Shortcuts (cont.)

class Thing
  attr_accessor :foo, :bar
end

thing = Thing.new
=> #<Thing:0x007fe008897278>
>> thing.methods
=> [:foo, :foo=, :bar, :bar=,

Attribute Shortcuts (cont.)

Attribute Shortcuts (cont.)

Lazy Initialization with Or-Equals

class Cookie
  def chips
    @chips ||= 10
  end
end

Query methods

class Person
  def child?
    @age < 18
  end
end

alice.age = 16
alice.child? #=> true

Note: query methods return a boolean by convention only

Bang methods

class Person
  def birthday!
    @age = @age + 1
  end
end

A Poorly-Encapsulated Object

class BadStudent
  attr_accessor :first_name, :last_name
end

joe = BadStudent.new
joe.first_name = "Joe"
joe.last_name = "Blow"
puts joe.first_name + " " + joe.last_name

A Well-Encapsulated Object

class GoodStudent
  def initialize first_name, last_name
    @first_name, @last_name = first_name, last_name
  end

  def full_name
    "#{@first_name} #{@last_name}"
  end
end

jane = GoodStudent.new("Jane", "Brain")
puts jane.full_name

A Well-Encapsulated Object (cont)

Next Lesson   Previous Lesson

Outline

[menu]

/