Ruby self.extended被称为实例方法

问题描述:

module Country
  def location
    puts "location"
  end

  def self.included(base)
    def cities
      puts "cities"
    end
  end

  def self.extended(base)
    def animals
      puts "animals"
    end
  end
end

class Test
  include Country
end

class Test2
  extend Country
end

据我了解,将模块作为实例方法包含时将调用self.included,而将模块作为静态类方法扩展时将调用self.extended.

As far as I understand, self.included will be invoked when the module is being included as instance method where as self.extended will be invoked when the module is being extended as static class method.

但是当我在同一个文件中有两个类时,为什么它不会引发错误

But when I have two class in the same file, why it's not throwing error

Test.new.animals

Test.new.animals

=>动物

如果我删除了Test 2类,

And If I removed the Test 2 class,

 # class Test2
  # extend Country
# end

Test.new.animals

Test.new.animals

=>没有方法错误

def bar(没有显式的 definee (即def foo.bar))在最接近的词法包围模块中定义了bar.对于所有三个def,最接近的词法包围模块始终是Country,因此,这三个方法都在Country模块中定义.

def bar without an explicit definee (i.e. def foo.bar) defines bar in the closest lexically enclosing module. The closest lexically enclosing module for all three of your defs is always Country, so all three methods are defined in the Country module.

如果要定义 singleton方法,则可以使用

If you want to define a singleton method, you could use

module Country
  def self.extended(base)
    def base.animals
      puts "animals"
    end
  end
end

有关更多信息,请参见 Ruby,什么类可以在没有显式接收者的情况下获得方法? 详细信息.

See Ruby what class gets a method when there is no explicit receiver? for more details.