Ruby 对象';方法查找路径(模块和方法覆盖)

Ruby 对象';方法查找路径(模块和方法覆盖),ruby,Ruby,我无法理解为什么这个对象如此聪明,以至于即使是第一次执行,也会忽略下面的代码块 它正在搜索的方法位于每个模块上 class A include B,C,D,B end ruby是否保留了一个模块名数组(显然它称为D)?我不是100%理解你的问题,但我尽了最大努力 Ruby实际上会记住哪些模块包含在类中,并将这些模块合并到方法的查找路径中。您可以使用a.included\u modules 包含模块中的方法放在当前类中定义的模块之上。请参见此示例: class X def foo

我无法理解为什么这个对象如此聪明,以至于即使是第一次执行,也会忽略下面的代码块

它正在搜索的方法位于每个模块上

class A
  include B,C,D,B
end

ruby是否保留了一个模块名数组(显然它称为
D
)?

我不是100%理解你的问题,但我尽了最大努力

Ruby实际上会记住哪些模块包含在类中,并将这些模块合并到方法的查找路径中。您可以使用
a.included\u modules

包含模块中的方法放在当前类中定义的模块之上。请参见此示例:

class X
  def foo
    puts 'Hi from X'
  end
end

module AnotherFoo
  def foo
    puts "Hi from AnotherFoo"
    super
  end
end

class Y < X
  include AnotherFoo
end

y = Y.new
y.foo
# Hi from another foo
# Hi from X

class Y < X
  include AnotherFoo
  def foo
    puts "Hi from Y"
    super
  end
end

y.foo
# Hi from Y
# Hi from another foo
# Hi from X
X类
德福
放“你好,来自X”
结束
结束
模块AnotherFoo
德福
放上“你好,来自另一个朋友”
超级的
结束
结束
Y类

您可以看到方法解析顺序:子类->包含的模块->父类。您还可以看到模块总是只包含一次。因此,如果一个类已经包含一个模块,它将不会再次被重新包含。

a.included\u modules?这对我来说已经足够好了,可以告诉我ruby保留了一个模块名数组,我猜它在这里做的第一件事就是遍历这个数组的所有元素,看看是否有什么地方出错。谢谢你说“如果出了问题”是什么意思?Ruby有一个定义良好的方法解析顺序。这意味着当提到函数名时,它用来查找您正在调用的实际函数的算法。正如我所说,顺序是class->included modules(按顺序尝试)->父类。如果其中一个包含具有定义名称的方法,则会使用该方法并中止搜索。事实上,通过说可能出现问题,我并不是说出现了问题,我只是说,显然,当我们询问模块是否响应某种消息时,ruby所做的是询问自己包含的模块,然后做一些事情,正如您之前所说的“不会重新引入包含的模块”。现在,我理解了关于方法查找路径的另一部分,尽管我知道它是如何工作的,因为它非常简单。我只是让所有这些模块都使用相同的名称,我试图猜测为什么我的对象忽略了我声明为最后一个的模块,即使它已经在。A.包含的模块?确实有帮助。