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