DEV Community

Adam Lombard
Adam Lombard

Posted on • Updated on

Ruby: class methods vs. instance methods

In Ruby, a method provides functionality to an Object. A class method provides functionality to a class itself, while an instance method provides functionality to one instance of a class.

Consider the following Ruby class:

class SayHello
  def self.from_the_class
    "Hello, from a class method"

  def from_an_instance
    "Hello, from an instance method"
Enter fullscreen mode Exit fullscreen mode

This would yield the following:

>> SayHello.from_the_class
=> "Hello, from a class method"

>> SayHello.from_an_instance
=> undefined method `from_an_instance' for SayHello:Class

>> hello =
>> hello.from_the_class
=> undefined method `from_the_class' for #<SayHello:0x0000557920dac930>

>> hello.from_an_instance
=> "Hello, from an instance method"
Enter fullscreen mode Exit fullscreen mode

We cannot call an instance method on the class itself, and we cannot directly call a class method on an instance.

Railstips has a nice article with more detail and a discussion of alternative ways of creating both class methods and instance methods.

See also: Python: class vs. instance vs. static methods

Top comments (5)

adamlombard profile image
Adam Lombard

Thanks for the deeper dive on that, Michael!

son1112 profile image
Anderson Reinkordt • Edited

I am playing with a decision to define an instance method within a module, that acts as a 'proxy' to the class method of the same name.

For example, let's say the following exists in a module:

default = foobarbitz_entangling_thing.raw_metadata.dig("ooooooh_realllly?") == true ? self.class.ready_to_start_digggging_early_at : self.class.ready_to_start_diggggging_at

def self.ready_to_start_diggggging_at
  ... does things

def self.ready_to_start_digggging_early_at
  ... does things
Enter fullscreen mode Exit fullscreen mode

I want to reduce the length of the 'default' assignment. The condition statement reduction is trivial for the first part, so it ends up looking like this with a helper method:

default = oooh_realllly? ? self.class.ready_to_start_digggging_early_at : self.class.ready_to_start_diggggging_at
Enter fullscreen mode Exit fullscreen mode

I would like to add the following simply for reducing this line length as minimally as possible.

def ready_to_start_diggggging_at

def ready_to_start_digggging_early_at
Enter fullscreen mode Exit fullscreen mode

This reduces the line to about here:

default = oooh_realllly? ? ready_to_start_digggging_early_at : ready_to_start_diggggging_at
Enter fullscreen mode Exit fullscreen mode

Aside from renaming methods to reduce length, my question is this:

Is this bad practice, bad pattern, a bad dog that will bite me later? Or is this okay and common practice?

It feels weird to me to call a module's defined class method from that same module's instance method of the same name. The other way around, sure that happens all of the time. I am hesitating; probably for good reason?

Note: These are silly method names created just for an example of a long method name. For context, I am attempting to do this minimally, so I am avoiding method name changes and anything else really that will add to review discussion rabbit holes. KISS

Thanks for taking time read this!

mth0158 profile image

Thanks for this @citizen428 !

matejsarlija profile image