Ruby — Class-level and Instance-level methods of the same name | Ryan Bosinger

Ryan Bosinger

Web App Developer, Victoria BC

Ruby — Class-level and Instance-level methods of the same name

Here’s something you can do with Ruby that some people don’t seem to know: When writing a class you can create 2 methods with the same name if one is instance level and one is class level.

Let’s say I have this Donkey class:

class Donkey
  def initialize(name:)
    @name = name
  end

  def kick
    puts "#{@name} just kicked!"
  end
end

It’s your everyday Donkey class. You can use it like so:

d = Donkey.new(name: "Kimmy Jimmel")
d.kick

=> Kimmy Jimmel just kicked!

You probably know that you can also write it like this:

class Donkey
  def self.kick(name:)
    puts "#{name} just kicked!"
  end
end

Donkey.kick(name: "DeMarco")

Here we’ve written a class-level method and removed the initializer. We essentially have a module. We can use it like this:

Donkey.kick(name: "DeMarco")

=> DeMarco just kicked!

Now we’ve got more of a functional approach wherein we’re not keeping any state in an object. Sometimes this is useful. But, guess what? You can mix them too.

class Donkey
  def initialize(name:)
    @name = name
  end

  def self.kick(name:)
    puts "#{name} just kicked!"
  end

  def kick
    self.class.kick(name: @name)
  end
end

Now both are available:

d = Donkey.new(name: "Kimmy Jimmel")
d.kick

=> Kimmy Jimmel just kicked!

Donkey.kick(name: "DeMarco")

=> DeMarco just kicked!

This can be useful for a few reasons that I’ve run into. In one scenario I find myself writing a lot of small “helper” style methods on a class. They may be related to methods meant to be run on an instance (like d.kick) but also be useful on their on elsewhere in the codebase. The need to instantiate an instance of this class and provide it’s required data may feel like overkill for the task at hand.

Cheers,
Ryan