class << notation in modules

metaprogramming, mixins, module, ruby

Solution

`class <<` must always be followed by an object. Just `class <<; end` is a syntax error. In your case it looks like it works because of the following:

class <<
  def class_method
    puts "From inside the class_method"
  end
end

is the same as

class << def class_method
    puts "From inside the class_method"
  end
end

which is the same as

temp = def class_method
  puts "From inside the class_method"
end
class << temp
end

which is the same as

def class_method
  puts "From inside the class_method"
end
class << nil
end

which is the same as

def class_method
  puts "From inside the class_method"
end

Of course that doesn't actually define a class method. It defines an instance method.

Problem

I'm trying to mix a module into a class, and I want some of the methods to behave as class methods and others to be instance methods. However, I don't want to both `include` and `extend` the module. I'd rather just `include` it. When I wrap the methods I want to be class methods in this notation, it works: ``` class << # ... end ``` However, when I use this notation it doesn't work: ``` class << self # ... end ``` I suspect the `self` keyword is establishing an explicit binding to the module, rather than the class it gets mixed into. But I've not seen any documentation that recommends leaving the `self` keyword off when using the `class <<` notation. Does anyone know what's going on with this? UPDATE: Here's some sample code for more clarity: ``` module M class << def class_method puts "From inside the class_method" end end def instance_method puts "From inside the instance_method" end end class Object include M end class C end C.class_method obj = C.new obj.instance_method ```

Original source