像Math这样的Ruby类方法可以作为实例方法使用include吗?

时间:2013-06-08 15:22:03

标签: ruby class methods include

考虑:

module A
  def self.a; puts "a"; end;
  def aa; A.a; end;
end
include A
aa
a

aa有效,但不是a。是否有A.a可用的技巧a正如include Math使log可用Math.log一样?我怀疑的方法是为每个a方法编写一个self.a方法,但有没有办法避免这种方法?

3 个答案:

答案 0 :(得分:1)

你可能正在寻找extend self

module A
  def a; puts "a"; end;
  extend self
end

A.a

include A
a

答案 1 :(得分:1)

基于其他人的答案,我认为我想要的是:

module A
  module Functions
    def a
      puts 'a'
    end
  end
  extend Functions
end
# a is a module function of A
A.a
# Explicitly include these functions into one's instance
include A::Functions
a

现在可以包含A而不用方法污染他们的实例空间...... 除非明确地使用include A::Functions

答案 2 :(得分:0)

如果您有权访问模块源,那么有一个技巧,如果不这样做,还有一个技巧。如果这样做,这将是模块A

module A
  def a
    puts 'a!'
  end
  module_function :a
end

所有这些都会调用a

A.a
include A; a

即使您无法访问该模块的源代码,仍然可以通过少量(很多)元编程来实现:

SomeMod.instance_methods(false).each {|method| SomeMod.__send__(:module_function, method.to_sym)}

仅当方法仅在原始模块中定义为实例方法时才有效。

如果你想将它们定义为类方法,只在包含时生成实例:

module A
  def self.a
    puts 'a'
  end
  def self.included(klass)
    A.singleton_class.instance_methods(false).each do |m|
      klass.__send__(:define_method, m.to_sym) do |*args|
        A.__send__(m.to_sym, *args)
      end
    end
  end
end