开发者

Ruby: Is it possible to define a class method in a module?

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.

Is i开发者_StackOverflow社区t 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.


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

 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

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


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

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.


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.

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'


Just wanted to extend Oliver's answer Define Class methods and instance methods together in a module.

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)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜