Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

class << notation in modules

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
like image 478
Nathan Avatar asked May 27 '12 16:05

Nathan


1 Answers

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.

like image 173
sepp2k Avatar answered Sep 30 '22 08:09

sepp2k