# A little helper from _why
class Object
def metaclass
class << self; self; end
end
end
# A module with hooks
module Hooks
def self.included(base)
puts "including M"
end
def self.extended(base)
puts "extending using M"
end
def includes_hooks?
true
end
end
# A couple classes
class Foo; end
class Bar; end
# Prints "extending using M"
Foo.extend(Hooks)
# Prints "including M"
Bar.metaclass.send(:include, Hooks)
# Both return true
Foo.includes_hooks?
Bar.includes_hooks?
# Check inheritance tree
Foo.metaclass.ancestors
#=> [Hooks, Class, Module, Object, Kernel]
Bar.metaclass.ancestors
#=> [Hooks, Class, Module, Object, Kernel]
extend方法是在向metaclass里加代码.类自定义的类方法(非Class类的实例方法)也是在metaclass里.所以metaclass.send(:include,Hooks)和extend的是一样的.
>> o=Object.new
=> #<Object:0xb752670c>
>> o.metaclass
=> #<Class:#<Object:0xb752670c>>
>> o.metaclass.send(:include,Hooks)
including M
=> #<Class:#<Object:0xb752670c>>
>> o.includes_hooks?
=> true
>> ob=Object.new
=> #<Object:0xb751eb38>
>> ob.extend Hooks
extending using M
=> #<Object:0xb751eb38>
>> ob.includes_hooks?
=> true
include => includes code into class.
extend => extends using module, appends class methods.加到metaclass里
bar = Bar.new
bar - object of class Bar
bar.class - class of object bar
Bar - class Bar, object of class Class
Bar.metaclass - class of class Bar