Ruby: 有没有可能在模块中定义一个类方法?

假设有三个类: ABC。我希望每个类都有一个类方法,比如说 self.foo,它对于 ABC具有完全相同的代码。

有没有可能在一个模块中定义 self.foo,并将这个模块包括在 ABC中?我尝试这样做,并得到一个错误消息说,foo是不能识别的。

57797 次浏览

是的

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

我应该补充一个可能的注意事项——如果模块是所有的类方法——最好只在 Model 中使用 extend ModuleName,并直接在模块中定义方法——而不是在 Module 中使用 ClassMethod 模块,比如 la

 module ModuleName
def foo
# stuff
end
end
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

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

module Foo
extend ActiveSupport::Concern


module ClassMethods
def some_method
# stuff
end
end
end

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

这是使得 ruby 如此特别的基本 ruby Mixin 功能。 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'

我只是想给奥利弗一个答复 在模块中一起定义 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)