Ruby模块查找路径的行为如何?

时间:2013-12-13 03:17:26

标签: ruby

module A
  def go
    p 'go'
  end
end

module B
  extend self
  include A
  def start
    go
  end
end

# doesn't work
# B.start

module C
  include A
  extend self
  def start
    go
  end
end

# works
C.start

module Constants
  HELLO = "Hello!"
end

module D
  extend self
  include Constants
  def start
    p HELLO
  end
end

# works
D.start

有人可以向我解释一下吗?如果在C.start之前include A extend selfConstants如何运作?如果我只包括{{1}}?

,订单怎么样?

任何帮助都将不胜感激,谢谢。

1 个答案:

答案 0 :(得分:0)

  

为什么D.start有效?

因为extend self将方法start添加到D的单例类中。看下面的两个例子:

没有extend self

module Constants
  HELLO = "Hello!"
end

module D
  #extend self
  include Constants
  def start
    p HELLO
  end
end

D.singleton_methods # => []

extend self

module Constants
  HELLO = "Hello!"
end

module D
  extend self
  include Constants
  def start
    p HELLO
  end
end

D.singleton_methods # => [:start]
  

为什么B.start不起作用?

这是因为您首先将模块B的方法添加到其单例方法中,然后包含模块A的方法,因此#go未添加到{的单例方法中{1}}。看看下面的两个例子。

首先B然后include A

extend self可以在这里使用,因为您首先包含了从B.startA的方法。然后将B的所有方法(在B中定义并包含在A中的方法)添加到B的单例类中。因此,B内的#go来电已成功。

B.start

首先module A def go p 'go' end end module B include A extend self def start go end end B.singleton_methods # => [:start, :go] ,然后是extend self

include A在此不起作用,因为您首先将方法从B.start扩展到A,然后只将B中的所有方法添加到单个类的B。之后,您添加了B中的方法,这就是A未添加到#go的单例类的原因。因此,B内的#go来电未成功。

B.start

我希望现在可以理解为什么module A def go p 'go' end end module B extend self include A def start go end end B.singleton_methods # => [:start] 有效了。