Chapter 9 - Mixins

Exercise 1: Inheritance abuse

We have Drill and ElectricCar classes that need power_level and power_level= attribute accessor methods, a charge method, and a rev_motor method. We also have a Phone class that only needs the power_level, power_level=, and charge methods.

Someone has created a class with all of these methods, and made it the superclass of Drill, ElectricCar, and Phone. All three classes now have all the methods they need, but Phone also has a rev_motor method, and maybe it shouldn’t.

class MotorizedBatteryPoweredThing
  attr_accessor :power_level

  def initialize
    self.power_level = 0
  end

  def charge
    self.power_level += 1
  end

  def rev_motor
    puts "Revving motor!"
  end
end

class Drill < MotorizedBatteryPoweredThing
end

class ElectricCar < MotorizedBatteryPoweredThing
end

class Phone < MotorizedBatteryPoweredThing
end

drill = Drill.new
drill.charge
puts drill.power_level

car = ElectricCar.new
car.charge
car.rev_motor

phone = Phone.new
phone.charge
# Maybe a Phone shouldn't have this method...
phone.rev_motor

Here’s the output for the above code…

1
Revving motor!
Revving motor!

See if you can create a Motorized module with a rev_motor method, and a BatteryPowered module with power_level, power_level=, and charge methods. Remember to avoid using an initialize method in a module; you’ll probably need to use the ||= operator to set an initial value for the power level.

Then, mix those modules into the Drill, ElectricCar, and Phone classes, as appropriate. The Drill and ElectricCar classes should have power_level, power_level=, charge, and rev_motor methods. The Phone class should have all of those methods except the rev_motor method.

When you’re ready, have a look at the solution.