DEV Community

Adam Lombard
Adam Lombard

Posted on Edited 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"
  end

  def from_an_instance
    "Hello, from an instance method"
  end
end
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 = SayHello.new
>> 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.


Was this helpful? Did I save you some time?

🫖 Buy Me A Tea! ☕️


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

Top comments (4)

Collapse
 
adamlombard profile image
Adam Lombard •

Thanks for the deeper dive on that, Michael!

Collapse
 
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
end

def self.ready_to_start_digggging_early_at
  ... does things
end
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
  self.class.ready_to_start_diggggging_at
end

def ready_to_start_digggging_early_at
  self.class.ready_to_start_digggging_early_at
end
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!

Collapse
 
mth0158 profile image
Mathieu EUSTACHY •

Thanks for this @citizen428 !

Collapse
 
matejsarlija profile image
matej •

Freaky.