こんにちは、鈴木です。
モジュールの include と extend は慣れるまではややこしいですね。
ライブラリを使用する時に、提供されているモジュールを include すれば良いのか、extend すれば良いのか迷うこともあると思います。
えぇーい、面倒くさい! ということで生まれたかどうかは知りませんが、モジュールに関する頻出パターンをご紹介します。
「モジュールが include された時に、クラスメソッドとインスタンスメソッドの両方を追加する」という手法です。
この手法を使うと、何も考えずに include すれば便利なクラスメソッドやインスタンスメソッドが使えるようになるモジュールを作ることができます。
includeされた時にクラスメソッドとインスタンスメソッドを同時に追加する頻出パターン
このような時の頻出パターンとして、以下のようなコードが書かれることが多いです。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | module YourModule   def self.included(base)     base.extend(ClassMethods)   end   module ClassMethods     def hello       puts 'Hello!'     end   end   def bye     puts 'Bye!'   end end | 
YourModule を include すると、bye メソッドはインスタンスメソッドとして使えるようになります。そして、ネストしている ClassMethods モジュールで定義されている hello はクラスメソッドとして使えるようになります。
モジュールの include と extend
この動作を理解するために、モジュールの include と extend についておさらいしましょう。
例として、ログ出力機能を提供する Logging というモジュールがあるとします。
| 1 2 3 4 5 | module Logging   def log(message)     puts message   end end | 
Logging モジュールを include すると、インスタンスメソッドとして log メソッドを使えるようになります。
| 1 2 3 4 5 6 | class Momotaro   include Logging end momotaro = Momotaro.new momotaro.log('桃から生まれた') | 
Logging モジュールを extend すると、クラスメソッドとして log メソッドを使えるようになります。
| 1 2 3 4 5 | class Kintaro   extend Logging end Kintaro.log('マサカリを担いだ') | 
include されたときに included が呼ばれる
モジュールに included メソッドを定義しておくと、モジュールが include された時に呼び出されます。
| 1 2 3 4 5 6 7 8 9 10 | module Logging   def self.included(base)     # (2) base には Momotaro クラスが渡される   end end class Momotaro   # (1) Momotaro クラスが Logging を include すると   include Logging end | 
included の引数は include したクラスやモジュールです。
それに対して extend すれば、include されたときにクラスメソッドも同時に追加することができる、という仕組みです。
まとめ
モジュールの include と extend の動作、そして include したときに included メソッドが呼ばれることが分かれば、冒頭の頻出パターンのコードを理解することができますね。

 
						