included() vs extended()

# 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

你可能感兴趣的:(Ruby)