1
\$\begingroup\$

I have a Ruby class into which I want to include both class and instance methods. Following the pattern described in "Ruby Pattern: Extend through Include", I'm currently using the following:

class SomeObject

  include SomeObject::Ability

  def self.some_builder_method(params)
    # use some_class_method ...
  end

end

module SomeObject::Ability

  module ClassMethods

    def some_class_method(param)
      # ...
    end

  end

  def self.included(klass)
    klass.extend(ClassMethods)
  end

  def some_instance_method
    # ...
  end

end

I'd rather not make two separate modules, one being included and the other being extended, because all the methods in my module logically fit together. On the other hand, this pattern requires me to:

  1. Define an additional ClassMethods module.
  2. Write a boilerplate self.included method for every module.

Is this the most idiomatic way to approach this?

\$\endgroup\$
1
  • 1
    \$\begingroup\$ AFAIK self.included + .extend(ClassMethods) is pretty much the way to do it. If you're using Rails, you can use ActiveSupport::Concern which handles this kind of thing. \$\endgroup\$ Commented Mar 9, 2013 at 15:29

1 Answer 1

2
\$\begingroup\$

You're doing it right :) It's a very common idiom, and widely accepted as the preferred way to handle this.

In case you're still in doubt, here are a few examples of the same pattern found in major projects out in the wild: sidekiq, mongoid and datamapper.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.