Ruby:是否可以在模块中定义类方法?

时间:2011-01-15 11:37:19

标签: ruby

假设有三个班级:AB& C。我希望每个类都有一个类方法,比如说self.foo,它与AB&的代码完全相同。 C

是否可以在模块中定义self.foo,并将此模块包含在AB& C?我尝试这样做并收到一条错误消息,指出foo无法识别。

5 个答案:

答案 0 :(得分:95)

是的

module Foo
  def self.included(base)
    base.extend(ClassMethods)
  end
  module ClassMethods
    def some_method
      # stuff
    end
  end
end

我应该添加一个可能的注释 - 如果模块将成为所有类方法 - 最好只使用模型中的extend ModuleName并直接在模块中定义方法 - 而不是在内部使用ClassMethods模块模块,la

 module ModuleName
   def foo
     # stuff
   end
 end

答案 1 :(得分:42)

module Common
  def foo
    puts 'foo'
  end
end

class A
  extend Common
end

class B
  extend Common
end

class C
  extend Common
end

A.foo

或者,您可以在以后扩展课程:

class A
end

class B
end

class C
end

[A, B, C].each do |klass|
  klass.extend Common
end

答案 2 :(得分:20)

Rails 3引入了一个名为ActiveSupport::Concern的模块,其目标是简化模块的语法。

module Foo
  extend ActiveSupport::Concern

  module ClassMethods
    def some_method
      # stuff
    end
  end
end

它允许我们在模块中保存几行“样板”代码。

答案 3 :(得分:17)

这是ruby mixin的基本功能,使ruby如此特别。 虽然extend将模块方法转换为类方法,但include将模块方法转换为包含/扩展类或模块中的实例方法。

module SomeClassMethods
  def a_class_method
    'I´m a class method'
  end
end

module SomeInstanceMethods
  def an_instance_method
   'I´m an instance method!'
  end
end

class SomeClass
  include SomeInstanceMethods
  extend SomeClassMethods
end

instance = SomeClass.new
instance.an_instance_method => 'I´m an instance method!'

SomeClass.a_class_method => 'I´m a class method'

答案 4 :(得分:0)

只想扩展Oliver的答案 在模块中一起定义Class方法和实例方法。

module Foo
 def self.included(base)
   base.extend(ClassMethods)
 end
 module ClassMethods
   def a_class_method
     puts "ClassMethod Inside Module"
   end
 end

 def not_a_class_method
   puts "Instance method of foo module"
 end
end

class FooBar
 include Foo
end

FooBar.a_class_method

FooBar.methods.include?(:a_class_method)

FooBar.methods.include?(:not_a_class_method)

fb = FooBar.new

fb.not_a_class_method

fb.methods.include?(:not_a_class_method)

fb.methods.include?(:a_class_method)