タイトルにあることを 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
というクラスは Iterable
を include
しようとするけど要求されている each
メソッドの定義を持っていないので例外が発生する、という様子。
うれしいところ
Ruby はコアに Enumerable
や Comperable
といった「要求されるメソッドさえ定義しておけば、後はいい感じに便利なメソッドを使える、というモジュールが用意されている。
そのようなモジュールを自分で定義して提供するときに、要求する実装 (= メソッド) を宣言的に書けて、あまつさえ (実行時でも) 検証してくれるので便利。
いけていないところ
Module::Requirement
を include
したモジュールを include
する時点で構造を検証するので、次のように書いてもエラーになる:
class List include Iterable def each # ... end end
静的検査に近づこうというコンセプトなので、仕方がないと思いつつ、どうにかなるとよいと思う。
include
すると要求するメソッドのボディを raise NotImplementedError
と定義する、というのはありかもしれない。