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

时间:2022-02-19 11:10:52

Say there are three classes: A, B & C. I want each class to have a class method, say self.foo, that has exactly the same code for A, B & C.

假设有三个类:A、B和c。我希望每个类都有一个类方法,比如self。foo A B C的代码完全相同。

Is it possible to define self.foo in a module and include this module in A, B & C? I tried to do so and got an error message saying that foo is not recognized.

是否有可能定义自我。在模块中添加foo,并将该模块包含在a、B和C中?我试图这么做,结果得到一个错误消息,说foo不能识别。

4 个解决方案

#1


39  

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

Or, you can extend the classes afterwards:

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

class A
end

class B
end

class C
end

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

#2


91  

Yep

是的

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

One possible note I should add - if the module is going to be ALL class methods - better off just using extend ModuleName in the Model and defining the methods directly in the module instead - rather than having a ClassMethods module inside the Module, a la

我应该补充一点——如果模块是所有类方法——最好在模型中使用extend ModuleName并直接在模块中定义方法——而不是在模块中使用ClassMethods模块,la

 module ModuleName
   def foo
     # stuff
   end
 end

#3


15  

Rails 3 introduced a module named ActiveSupport::Concern which has the goal of simplifying the syntax of modules.

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

module Foo
  extend ActiveSupport::Concern

  module ClassMethods
    def some_method
      # stuff
    end
  end
end

It allowed us to save a few lines of "boilerplate" code in the module.

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

#4


11  

This is basic ruby mixin functionality that makes ruby so special. While extend turns module methods into class methods, include turns module methods into instance methods in the including/extending class or module.

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

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'

#1


39  

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

Or, you can extend the classes afterwards:

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

class A
end

class B
end

class C
end

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

#2


91  

Yep

是的

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

One possible note I should add - if the module is going to be ALL class methods - better off just using extend ModuleName in the Model and defining the methods directly in the module instead - rather than having a ClassMethods module inside the Module, a la

我应该补充一点——如果模块是所有类方法——最好在模型中使用extend ModuleName并直接在模块中定义方法——而不是在模块中使用ClassMethods模块,la

 module ModuleName
   def foo
     # stuff
   end
 end

#3


15  

Rails 3 introduced a module named ActiveSupport::Concern which has the goal of simplifying the syntax of modules.

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

module Foo
  extend ActiveSupport::Concern

  module ClassMethods
    def some_method
      # stuff
    end
  end
end

It allowed us to save a few lines of "boilerplate" code in the module.

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

#4


11  

This is basic ruby mixin functionality that makes ruby so special. While extend turns module methods into class methods, include turns module methods into instance methods in the including/extending class or module.

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

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'