从Ruby中该类包含的模块调用类方法

时间:2012-01-06 16:35:20

标签: ruby multiple-inheritance

在下面的代码中,我想调用包含done内部模块的类的类方法self.hello

说明:

A::bonjour会致电Mod::helloB::ciao

我希望能够在Mod::hello中检测到“通话类”(A或B),以便能够拨打A::doneB::done

module Mod
 def self.hello
  puts "saying hello..."
 end
end

class A
 include Mod

 def self.bonjour
  Mod::hello 
 end

 def self.done
  puts "fini"
 end
end

class B
 include Mod

 def self.ciao
  Mod::hello
 end

 def self.done
  puts "finitto"
 end
end

1 个答案:

答案 0 :(得分:4)

虽然(也许)不像Niklas的回答那么干净,但它仍然很容易实现,而且IMO比OP中显示的使用模式更清晰,它依赖于知道混合了哪个模块。

(当存在其他方法时,我宁愿不必将参数传递给像这样的mixin方法。)

输出:

pry(main)> A::bonjour
saying hello...
fini
pry(main)> B::ciao
saying hello...
finitto

胆量:

module Mod
  module ClassMethods
    def hello
      puts "saying hello..."
      done
    end
  end

  def self.included(clazz)
    clazz.extend ClassMethods
  end
end

修改后的类声明,删除显式模块引用:

class A
  include Mod

  def self.bonjour
    hello
  end

  def self.done
    puts "fini"
  end
end

class B
  include Mod

  def self.ciao
    hello
  end

  def self.done
    puts "finitto"
  end
end

您还可以提供done的默认实施:

module Mod
  module ModMethods
    def hello
      puts "saying hello..."
      done
    end

    def done
      throw "Missing implementation of 'done'"
    end
  end

  def self.included(clazz)
    clazz.extend ModMethods
  end
end

正如对这篇文章的评论指出的那样,如果OP中的片段是对实际用例的忠实表示,那么您也可以使用extend(而不是include),让一切都更清洁:

module Mod
  def hello
    puts "saying hello..."
    done
  end

  def done
    raise NotImplementError("Missing implementation of 'done'")
  end
end

使用extend的课程:

class A
  extend Mod

  def self.bonjour
    hello
  end

  def self.done
    puts "fini"
  end
end