This summer, I’m learning Ruby on Rails at Metis, a 12-week class taught by some great folks from thoughtbot. This post is part of a series sharing my experience and some of the things I’m learning.

File this one under, “fool me once, shame on you; fool me twice, write a blog post.”

In Ruby we use the private method to define instance methods that are only accessible from within a class:

class HammerTime
  # Arbitrary public methods omitted

  private
  
  def stop
    puts "Can't touch this"
  end
end

Calling stop on an instance of the class HammerTime from somewhere other than within the class itself will result in an error:

HammerTime.new.stop
# => NoMethodError: private method `stop' called for #<HammerTime:0x00>

Given this, we might expect the same syntax to work for class methods:

class I
  # Arbitrary public methods omitted

  private

  def self.wanna
    puts "...dance with somebody"
    puts "...feel the heat with somebody"
  end
end

Surely we’ll get the same NoMethodError, right? Wrong:

I.wanna
# => ...dance with somebody
# => ...feel the heat with somebody

Instead, we’ll need to explicitly define this method as a private_class_method, like this:

class Domo
  # Arbitrary public methods omitted

  def self.arigato
    puts "Secret secret, I've got a secret"
  end
  private_class_method :arigato
end

And we’ll get the expected error, indicating this method is only accessible from within the class:

Domo.arigato
# => NoMethodError: private method `arigato' called for Domo:Class

Caveat emptor.