Ruby allows you to make private methods:

class Sample

  def foo
    :SNAFU
  end

  private

  def private_foo
    :PRIVATE_SNAFU
  end

end

Sample.new.foo
  #=> :SNAFU

Sample.new.private_foo
  #=> NoMethodError: private method `private_foo' called for #<Sample:0x007fa12192e130>

Ruby also allows you to make what other languages call “class methods.” Class methods are singleton methods of the class object, not instance methods of a Class’s object. Got it?

class Sample

  def self.bar
    :FUBAR
  end

end

Sample.bar
  #=> :FUBAR

Sample.new.bar
  #=> NoMethodError: undefined method `bar' for #<Sample:0x007fa12190d2a0>

Can we combine the two techniques to make private class methods?:

class Sample

  private

  def self.private_bar
    :PRIVATE_FUBAR
  end

end

Sample.private_bar
  #=> :PRIVATE_FUBAR

Nay nay! You cannot combine these two techniques to make a private class method. The private keyword does some modal thing with respect to instance methods being defined in the block, but the syntax def self.method_name is a different kind of thing. That different kind of thing applies to any object:

three = BasicObject.new

def three.to_i
  3
end

three.to_i
  #=> 3

The def something.method_name semantics ignores any declaration about privacy. Here’s a question: Where are the methods three.to_i and three.to_s defined? In something called a singleton class, also called an eigenclass. These methods are called singleton methods because they apply to three but not to anything else:

four = BasicObject.new

four.to_i
  #=> NoMethodError: undefined method `to_i' for #<BasicObject:0x007fa121856d20>

There’s another way to declare a singleton method. Behold:

class << four

  def to_i
    4
  end

end

four.to_i
  #=> 4

When you use the class << x ... end syntax, the code in the block is evaluated in the context of the singleton class of x for any object x. Note that it works just like defining instance methods in a typical class declaration. For example, we can include a module:1

module Mathy

  def * that
    self.to_i * that.to_i
  end

end

class << four

  include ::Mathy

end

four * 5
  #=> 20

What happens if we create a singleton method for a class object?

class << Sample

  def glitch
    'Gremlins Lurking In The Computer Hardware'
  end

end

This is not an instance method of Sample instances:

Sample.new.glitch
  #=> NoMethodError: undefined method `glitch' for #<Sample:0x007fa14b0c3340>

It’s a singleton method of the Sample object itself:

Sample.glitch
  #=> "Gremlins Lurking In The Computer Hardware"

Hey, what’s a class method anyways? It’s a method on the class, not a method on an instance of the class. In other words… Class methods are singleton methods of class objects, and thus you can define them with either def Sample.glitch or class << Sample.

Are there any reasons to use class << Sample? Consider this:

five = BasicObject.new

class << five

  private

  def puddy
    'high five!'
  end

end

five.puddy
  #=> NoMethodError: private method `puddy' called for #<BasicObject:0x007fa14a0279c8>

This is very interesting! You can create private singleton methods using the class << x syntax. You can’t using the def x.method_name syntax. So intuition suggests:

class << Sample

  private

  def bug
    :MOTH
  end

end

Sample.new.bug
  #=> NoMethodError: undefined method `bug' for #<Sample:0x007fa14b0976c8>

Sample.bug
  #=> NoMethodError: private method `bug' called for Sample:Class

Aha! That’s how to create private singleton methods for class objects.

homework

Explain this code:

class Sample

  class << self

    private

    def skunkworks
      :ADP
    end

  end

end

(discuss; also, I wrote a book, and it’s free to read online)

  1. You are thinking that you can .extend any object with a module too. Well, you can extend any instance of Object, but not an instance of BasicObject that isn’t also an instance of Object. Tricky raganwald!