Module が要求する実装を宣言して、実際に要求を満たしているか検証する

タイトルにあることを Ruby でやる実装を書いた:


aereal/module-requirement · GitHub

Swift / Objective-C の protocol は具象クラスがメソッドを実装していることを要求できるので、Ruby でも似たようなことをやってみる、というコンセプト。

使い方

require 'module/requirement'

module Iterable
  include Module::Requirement
  include Enumerable

  requires :each
end

class List
  include Iterable # => Module::Requirement::Error::NotMeetRequirements List must implement required methods: each
end

Iterable という each メソッドが定義されていることを期待するモジュールを定義して、List というクラスは Iterableinclude しようとするけど要求されている each メソッドの定義を持っていないので例外が発生する、という様子。

うれしいところ

Ruby はコアに EnumerableComperable といった「要求されるメソッドさえ定義しておけば、後はいい感じに便利なメソッドを使える、というモジュールが用意されている。

そのようなモジュールを自分で定義して提供するときに、要求する実装 (= メソッド) を宣言的に書けて、あまつさえ (実行時でも) 検証してくれるので便利。

いけていないところ

Module::Requirementinclude したモジュールを include する時点で構造を検証するので、次のように書いてもエラーになる:

class List
  include Iterable

  def each
    # ...
  end
end

静的検査に近づこうというコンセプトなので、仕方がないと思いつつ、どうにかなるとよいと思う。

include すると要求するメソッドのボディを raise NotImplementedError と定義する、というのはありかもしれない。