Calling super
Part of the Object Oriented Programming section of Coddy's Ruby journey. Lesson 24 of 57.
Inside an overriding method, super calls the superclass's version of the same method. The subclass can build on the result instead of repeating it:
class Greeter
def greet(name)
"Hello, #{name}"
end
end
class LoudGreeter < Greeter
def greet(name)
super.upcase + "!"
end
end
puts LoudGreeter.new.greet("Ada")Output:
HELLO, ADA!The most common use is initialize: the subclass takes an extra value, passes the shared ones to the superclass with super(...) and stores its own:
class Person
attr_reader :name, :age
def initialize(name, age)
@name = name
@age = age
end
end
class Student < Person
attr_reader :school
def initialize(name, age, school)
super(name, age)
@school = school
end
end
s = Student.new("Ada", 20, "MIT")
puts "#{s.name}, #{s.age}, #{s.school}"Output:
Ada, 20, MITThe three forms differ in what they pass. Bare super passes the same arguments the current method received; super() passes none; super(a, b) passes exactly those:
class Base
def show(*args)
"Base got #{args.inspect}"
end
end
class Child < Base
def show(a, b)
[super, super(), super(b)].join(" | ")
end
end
puts Child.new.show(1, 2)Output:
Base got [1, 2] | Base got [] | Base got [2]super can run anywhere in the method, or only under a condition. When the subclass's initialize takes other arguments than its parent's, bare super passes the wrong ones, which is a common ArgumentError:
class Logger
def log(message)
puts "LOG #{message}"
end
end
class QuietLogger < Logger
def log(message)
super unless message.start_with?("debug")
end
end
logger = QuietLogger.new
logger.log("started")
logger.log("debug x=1")
logger.log("done")Output:
LOG started
LOG doneChallenge
EasyComplete the classes. Person stores name and age, and its to_s returns Ada (36). Student adds a school: its initialize passes the name and age to super and its to_s returns Ada (20), studies at MIT, built from super. Teacher adds a subject in the same way and returns Bo (45), teaches maths.
The supplied code reads lines person Ada 36, student Ada 20 MIT or teacher Bo 45 maths and prints each object.
Your code goes in person.rb, student.rb and teacher.rb. main.rb holds the supplied input/output code and cannot be edited.
Try it yourself
require_relative 'person'
require_relative 'student'
require_relative 'teacher'
# Supplied input/output code: keep it as it is
input = []
while (line = gets)
input << line.chomp
end
input.each do |line|
kind, name, age, extra = line.split
person = case kind
when "student" then Student.new(name, age.to_i, extra)
when "teacher" then Teacher.new(name, age.to_i, extra)
else Person.new(name, age.to_i)
end
puts person
end
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Classes and Objects
Working With FilesDefining ClassesInstance VariablesMethods and selfto_s and inspectRecap - Library Card7Polymorphism and Duck Typing
PolymorphismDuck TypingAbstract Methodscase and ClassesRecap - Payment Methods2Accessors and Self
Readers and WritersCustom Settersself in MethodsIdentity and EqualityRecap - Contact List8Special Methods
Equality and hashOperator MethodsIndexing and AppendingCustom CollectionsRecap - Fractions11Project: Library Management
Books and MembersBorrowing Books3Class Methods and Variables
Class MethodsClass Instance VariablesConstantsFactory MethodsRecap - Coupon CodesPractice on your own: Online Ruby compiler