DEV Community

Jess Lee
Jess Lee

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
 
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
 
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
 
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.