views:

190

answers:

1

I suppose my question is exactly what the subject depicts, what does:

class << self

do in Ruby?

+10  A: 

First, the class << foo syntax opens up foo's singleton class (eigenclass). This allows you to specialise the behaviour of methods called on that specific object.

a = 'foo'
class << a
  def inspect
    '"bar"'
  end
end
a.inspect   # => "bar"

a = 'foo'   # new object, new singleton class
a.inspect   # => "foo"

Now, to answer the question: class << self opens up self's singleton class, so that methods can be redefined for the current self object (which inside a class or module body is the class or module itself). Usually, this is used to define class/module ("static") methods:

class String
  class << self
    def value_of obj
      obj.to_s
    end
  end
end

String.value_of 42   # => "42"

This can also be written as a shorthand:

class String
  def self.value_of obj
    obj.to_s
  end
end

Or even shorter:

def String.value_of obj
  obj.to_s
end

When inside a function definition, self refers to the object the function is being called with. In this case, class << self opens the singleton class for that object; one use of that is to implement a poor man's state machine:

class StateMachineExample
  def process obj
    process_hook obj
  end

private
  def process_state_1 obj
    # ...
    class << self
      alias process_hook process_state_2
    end
  end

  def process_state_2 obj
    # ...
    class << self
      alias process_hook process_state_1
    end
  end

  # Set up initial state
  alias process_hook process_state_1
end

So, in the example above, each instance of StateMachineExample has process_hook aliased to process_state_1, but note how in the latter, it can redefine process_hook (for self only, not affecting other StateMachineExample instances) to process_state_2. So, each time a caller calls the process method (which calls the redefinable process_hook), the behaviour changes depending on what state it's in.

Chris Jester-Young
@Jörg: +1 for edit (I wish SO provides the ability to upvote edits; oh well). That indeed is the more common use of `class << self`, to create class/module methods. I will probably expand on that use of `class << self`, as that is a much more idiomatic use.
Chris Jester-Young
gsub!("eigenclass", "singleton class"), see the upcoming method http://redmine.ruby-lang.org/repositories/revision/1?rev=27022
Marc-André Lafortune
@Marc-Andre: Wow, that was a very recent decision (capitulation? he seemed very reluctant throughout the thread) on Matz's part. Still, good that there is agreement on what to call it going forward.
Chris Jester-Young