Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby Can';t重新定义一个类';通过包含一个模块来创建实例方法?_Ruby - Fatal编程技术网

Ruby Can';t重新定义一个类';通过包含一个模块来创建实例方法?

Ruby Can';t重新定义一个类';通过包含一个模块来创建实例方法?,ruby,Ruby,我现在心情很好。我可以发誓这是有效的: module StubbedGreeting def sayit puts "StubbedGreeting" end end module RegularGreeting def sayit puts "RegularGreeting" end end class Greeting def sayit raise "Gotta catch me!" end end class GreetingIncl

我现在心情很好。我可以发誓这是有效的:

module StubbedGreeting
  def sayit
    puts "StubbedGreeting"
  end
end

module RegularGreeting
  def sayit
    puts "RegularGreeting"
  end
end

class Greeting
  def sayit
    raise "Gotta catch me!"
  end
end

class GreetingIncludes
  include RegularGreeting
end

begin
  Greeting.send(:include, StubbedGreeting)
  Greeting.new.sayit
rescue Exception
  puts "Exception raised"
end

GreetingIncludes.send(:include, StubbedGreeting)
GreetingIncludes.new.sayit
这里发生的是
Greeting.new.sayit
导致调用
rescue
块,忽略StubbedGreeting尝试的覆盖

但是,
GreetingIncludes.new.sayit
会产生“StubbedGreeting”,而不是例外

所以一个模块可以覆盖另一个模块的方法,但不能覆盖已经在类中直接定义的方法


我知道如何解决这个问题,我只是觉得很奇怪。

当包含模块时,它的方法按方法解析顺序放在类的方法和父类的方法之间。因此,在解析要调用的实际方法时,ruby首先按照以下顺序搜索该方法。如果找到匹配的方法,则中止搜索并使用此方法

  • 对象的单例类
  • 从最后一个包含到第一个包含在singleton类中的模块
  • 对象的类
  • 课程中包含的模块
然后对每个父类继续此操作,直到到达

如您所见,模块确实不能重写在类本身上定义的方法,因为模块在方法解析顺序中位于实际类的后面。如果确实需要重写这样的方法,可以使用
alias\u method
alias\u method\u chain
来“重命名”方法

在即将到来的Ruby 2.0中,将有一个新的类,它将在类之前包含模块,从而实现您想要的功能。但它还没有发布