RubyでDuckTyping

今日、知人に「DuckTypingのメリットが今一ピンとこない」と言われて実際にコード書いて説明をしたのだけれども、せっかくなのでエントリにまとめる。

DuckTypingとは、動的言語の柔軟性を表現する概念で以下の格言に由来する。

"If it walks like a duck and quacks like a duck, it must be a duck" (もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである)

つまり、アヒルのように振る舞うものは、実際にそれが何であろうとアヒルと見なすということになる。

もうちょっと言語よりな言い方をするのであれば、あるオブジェクトどのクラスに属するか考慮せず、どのようなインターフェースを持つかに注目するのがDuckTyping。

DuckTypingにおいて重要なことは「明示的な型チェックを避ける」と言うことで、どう言うことかと言うと

上記のようなコードを書いてしまうと、Duckクラスもしくはそれらを継承したクラスしか扱えなくなり、動的言語のメリットが失われてしまう。

その知人に紹介した簡単なDuckTypingの例が以下。

ここではwriteメソッドさえあれば、渡されたオブジェクトが何かは問わない。これをもうちょっと実際に使うようなコードに書き直すと以下のようになる。

やっていることは、ほとんどwrite_messageと同じだけど、こちらの方がまだピンとくると思う。Loggerはログを書き出すだけの簡単なクラスだが、DuckTypingを用いることによって、その書き出し先を柔軟に変更することができる。

実際はどんなオブジェクトが渡されるかわからないのでrespond_to?でメソッドの有無のチェックぐらいはした方がいい。

エラー処理をもうちょっと別の方法を取ってみる。

こちらの方法を取ると、仮に呼び出したメソッド内で例外が発生した場合もうまく処理することができる。個人的には大体こちらの手段を取ることが多い。

結構長くなったけど、大体こんな感じ。DuckTypingは慣れない人からするとよくわからないところも多いと思うけど、うまく使えれば結構便利な機能。使いすぎは禁物だけどうまく使っていくといいだろう。