Search code examples
rubymixins

How to mixin some class methods and some instance methods from a module in Ruby?


I have a module and would like to mixin some methods as class methods and some as instance methods.

For example:

module Foo
  def self.class_method
  end

  def instance_method
  end
end

class Bar
  include Foo
end

Usage:

Bar.class_method
Bar.new.instance_method

Is it possible to do this in Ruby?

If not, is it possible to define which methods are class methods and which are instance methods within the Bar class?

I don't want the same method defined as both a class and instance method.


Solution

  • This pattern is very common in Ruby. So common, in fact, that ActiveSupport::Concern abstracts it a bit.

    Your typical implementation looks like this:

    module Foo
      def self.included(other_mod)
        other_mod.extend ClassMethods
      end
    
      def instance_method
      end
    
      module ClassMethods
        def class_method
        end
      end
    end
    
    class Bar
      include Foo
    end
    

    You can't accomplish this easily as you describe without somehow splitting the included module into multiple pieces, though, unfortunately.