3
\$\begingroup\$

I'm learning about using inheritance and super in Ruby. This is a continuation of one of the exercises that is in a book I am reading.

I set up my Vehicle class to be the superclass. From there, MyCar and MyTruck inherit the Vehicle class's methods, by using the super method.

Both subclasses also have a MAX_SPEED constant, which is different for each. Each subclass also has its own .speed_up method, which outputs different strings depending on how fast the vehicle is going.

Is my code formatted correctly? It works, but I wonder how I can improve it, and if I am also using best practices in this case.

Should the year, color, model, and gasoline arguments be in the MyCar and MyTruck subclasses? Or should they remain in the Vehicle class?

The code below is also in my GitHub repository.

require 'date'

class Vehicle
  attr_accessor :speed, :on, :color
  attr_reader :year, :model, :gallons
  def initialize(year, color, model, gallons)
    @year = year
    @model = model
    @gallons = gallons
    @color = color
    @speed = 0
    @on = false
  end

  @@miles_per_gallon = 0

  def self.mileage(tank, miles)
    @@miles_per_gallon = miles / tank
  end

  def brake
    if self.speed == 0
      puts "You aren't moving! Yet you keep pushing the brake..."
    elsif self.speed >= 10
      self.speed -= 10
      puts "You slow down to #{self.speed} kilometers an hour."
    end
  end

  def shut_off
    if self.on == false 
      puts "Your car is already off."
    else
      self.on = false
      puts "You turn off your car. The engine falls silent."
    end
  end

  def turn_on
    if self.on == false
      self.on = true
      puts "The car's engine rumbles and sparks to life."
    else
      puts "Your car is already running!"
    end
  end

  def drive(distance)
    puts "You drive #{distance} miles."
    Vehicle.mileage(self.gallons, distance.to_i)
    puts "When you stop in the gas station, you find that your car gets #{@@miles_per_gallon} miles per gallon."
  end

  def look_at
    if Time.new.hour >= 17 && Time.new.hour < 19
      puts "The red light of the setting sun sparkles off the paint of your #{model}."
      puts "You feel nostalgic."
    elsif Time.new.hour >= 19 && Time.new.hour < 6
      puts "Your #{model} carves a dark outline in the moon's pale light."
      puts "You feel dangerous. Perhaps you should go find a street race?"
    else
      puts "You gaze at the body of your #{self.year} #{self.model}. Its #{color} paint sparkles in the sunlight."
      puts "You feel happy."
    end
  end

  def repaint(color)
    self.color = color
    puts "You changed your car's color to #{self.color}!"
    puts "Mmm, sexy."
  end

end

class MyCar < Vehicle

  def initialize(year, color, model, gallons)
    super(year, color, model, gallons)
  end

  MAX_SPEED = 180

  def speed_up
    if self.speed != MAX_SPEED
      self.speed += 10
      puts "You speed up to #{self.speed} kph."
      if self.speed == 120
        puts "The engine purrs, the wind flows past the open window next to your seat."
        puts "You reach serenity..."
      end
    else
      puts "The engine roars, putting forth maximum effort."
      puts "The speedometer is pinned to the max!"
    end
  end

end

class MyTruck < Vehicle

  def initialize(year, color, model, gallons)
    super(year, color, model, gallons)
  end

  MAX_SPEED = 140

  def speed_up
    if self.speed != MAX_SPEED
      self.speed += 10
      puts "You speed up to #{self.speed} kph."
      if self.speed == 120
        puts "The engine rumbles, the wind flows past the open window next to your seat."
        puts "You feel calm. If you had a dog, he'd probably be sticking his head out of the window."
      end
    else
      puts "The engine roars, putting forth maximum effort."
      puts "Your fuel gauge needle slowly trickles downward..."
    end
  end

end
\$\endgroup\$
2
\$\begingroup\$

MyTruck and MyCar do not need their own initialize, the behaviour looks the same as the one in MyVehicle.

if self.on == false may be replaced with if !self.on or predicates

def on?
  on
end
def off?
  !on
end

see http://ruby-for-beginners.rubymonstas.org/objects/predicates.html .

Using self.class.mileage(self.gallons, distance.to_i) allows to overwrite class method mileage.

self.speed == 0 may be replaced with self.speed.zero? because 0, 1 and the likes are Integer objects and respond to zero?, although this is opinionated, i.e. not every object respond to zero?.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.