DEV Community

Jess Lee
Jess Lee Subscriber

Posted on

Explain the 'super' keyword in ruby like I'm five

Top comments (8)

Collapse
 
edizle585 profile image
Elijah Logan

So lets say your mom makes super smacking pb &j's using her super smacking pb & j technique (all she does is remove the crust). But today mom had to hurry to work so brother B is making breakfast. Your not sure if b can make pb & j's like mom but he assures you that he's used ( super ) to get moms skill passed down to him so he's qualified. Using super B made you some super smacking pb & j's

class Mom-PB-Technique
def corner-cut(bread)
for corner in bread
corner.cut crust
return bread
end

class B-PB-Technique < Mom-PB-Technique
def corner-cut
super
end

Collapse
 
cathodion profile image
Dustin King • Edited

Doesn't doing B-PB-Technique < Mom-PB-Tecnhnique already give you all of mom's methods?

Collapse
 
zspencer profile image
Zee

Yes, it does. super is most useful when over-riding the behavior from a method provided in the ancestor chain. I would revise the example to the following:

class MomPBTechnique def corner_cut(bread) for corner in bread corner.cut crust end return bread end class MyPBTechnique < MomPBTechnique # I like *one* corner to not be cut! def corner_cut first_corner = self.bread[0] # Gets the first corner self.bread = bread.slice(1, -1) # Sets the bread to only the last 3 corners super # Calls the `corner_cut` method defined in `MomPBTechnique` return bread.unshift(first_corner) # Places the un-cut first corner back in the bread end end 

This more clearly demonstrates how super can be used to re-use-but-still-change behavior in the class hierarchy.

Collapse
 
johand profile image
Johan • Edited

With super you can call a method on the parent class with the same name in the child class, for example:

class Foo def my_method 'Hello there' end end class Bar < Foo def my_method super end end b = Bar.new b.my_method # => Hello there 
Enter fullscreen mode Exit fullscreen mode

Ruby search a method #my_method in the ancestor chain, if the method not exist it will show an error NoMethodError

`my_method': super: no superclass method `my_method' for #<Bar:0x0000564740b32170> (NoMethodError) 
Enter fullscreen mode Exit fullscreen mode
Collapse
 
cathodion profile image
Dustin King • Edited

When you inherit from a parent class, sometimes you want the child's method to behave slightly differently but still use the parent method's behavior.

Let's say you have a Greeter, and their job is to say hi to everyone they meet. If they have the person's name, they'll greet them by name.

class Greeter def greet(name=nil) if name puts "Hi, #{name}, nice to meet you!" else puts "Hi, nice to meet you!" end end end Greeter.new.greet #=> Hi, nice to meet you! Greeter.new.greet 'Jess' #=> Hi, Jess, nice to meet you! 
Enter fullscreen mode Exit fullscreen mode

Now suppose we hire a new greeter from the planet Marklar, who has a religious belief that everyone's name is Marklar. When their greet method calls super, it calls the greet method from their parent class, Greeter:

class MarklarGreeter < Greeter def greet super 'Marklar' end end MarklarGreeter.new.greet #=> Hi, Marklar, nice to meet you MarklarGreeter.new.greet 'Jess' #=> ArgumentError: wrong number of arguments (given 1, expected 0) 
Enter fullscreen mode Exit fullscreen mode

Okay, we still need greet to take a name parameter, so that we can use a MarklarGreeter anywhere we use a Greeter. This is called the Liskov Substitution Principle. I can't find a link that explains that like you're five, but it basically says an instance of a child class should be usable anywhere you can use an instance of the parent class.

class MarklarGreeter < Greeter def greet(name=nil) # We accept a name parameter here, but we ignore it # because everyone's name is Marklar super 'Marklar' end end MarklarGreeter.new.greet #=> Hi, Marklar, nice to meet you! MarklarGreeter.new.greet 'Jess' #=> Hi, Marklar, nice to meet you! 
Enter fullscreen mode Exit fullscreen mode

More info about Ruby's super here.

Collapse
 
chenge profile image
chenge

IMHO, super is alias of father or mother.

Collapse
 
imrawal profile image
Mee Lana • Edited

Is it good or bad to chain method in super like in below activerecord(5.1.6) code,

# 'delivery_timings' is a db field attribute class Country < ApplicationRecord # expects array of times and converts to string ie. ['08:00-12:00', '14:00-16:00'] to "08:00-12:00,14:00-16:00" def delivery_timings=(val) return super(val) if val.blank? super(val.reject(&:blank?).join(',')) end # converts string value to array of times ie. "08:00-12:00,14:00-16:00" to ['08:00-12:00', '14:00-16:00'] def delivery_timings return super if super.blank? super.split(',') end end 

Although the code works, I'm smelling on code(may be wrong).

Collapse
 
martin profile image
Martin Beentjes

super is your parent.