オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方という本を読んでダックタイピングについて学んだことをまとめます
ダックタイピングとは?
"If it walks like a duck and quacks like a duck, it must be a duck"
(もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである)
という言葉をRubyをやっているなら一度は聞いたことがあるかもしれません。私はこの言葉を聞いても正直何を言っているのか全くわかりませんでした。
実際Wikipediaなどで解説を読んでも全くピンときませんでした。
実例
理屈から入ってもわかりにくいので、まずはダックタイピングがRubyのどこで使われているのかを実際に見ていきましょう。これによってダックタイピングのなんとなくの雰囲気がつかめて理解の助けになるはずです。
実例1
この記事が説明は少ないですが、コードが短くて手っ取り早く雰囲気を掴みやすいかと思います。
実例2
別の方のQiita記事を参考にします。
RailsのActiveSupport
クラスにはblank?
メソッドが存在します。メソッド名から容易に想像できるように、オブジェクトが存在するかどうかを確認するためのメソッドです。
(実際には空っぽいかどうかで判定しています)
[].blank? #=> true # 空っぽい
{}.blank? #=> true # 空っぽい
[1].blank? #=> false
{a: 1}.blank? #=> false
''.blank? #=> true # 空っぽい
'1'.blank? #=> false
nil.blank? #=> true # 空っぽい
true.blank? #=> false
false.blank? #=> true # 空っぽい
このようにblank?
メソッドはArray
であれString
であれ応答できるようになっています。
次に実際にblank?
の中身を見て見ましょう。
# 実際にはもっとありますが、説明のためかなり省略しています。
class Object
def blank?
# ここが重要
# resopond_to?メソッドを使うことによって
# empty?メソッドを知っているオブジェクトに対してはempty?を使い、その結果を返す
# 知らないオブジェクトに対しては処理を変えている。この場合emptyを知らなかったらfalseが返る。
respond_to?(:empty?) ? !!empty? : !self
end
end
class Array
alias_method :blank?, :empty?
end
class Hash
alias_method :blank?, :empty?
end
class Numeric
# どんなNumberもblankではない
def blank?
false
end
end
実際にはもっとありますが、説明のためかなり省略しています。全部見たい方はこちらから
このような記述によってblank?
メソッドは全く知らないクラスに対しても、empty?
に応答できる場合はそれを使うという動きが実現できます。
このことが
"If it walks like a duck and quacks like a duck, it must be a duck"
(もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである)
という一見何を言っているのかわかりづらい、言葉の意味になります。
ダックタイピングのメリットとは?
ここまで説明してきたダックタイピングですが、どのようなメリットがあるのでしょうか?
この質問に対しては
【OOP入門】Rubyでダックタイピングを理解する
この方の記事を参考にされるのがいいです。
上の例でいうと私もまだはっきりとは理解できていないのですが、、、
- メンテナンスコストが下がる
- case文の肥大化が抑えられる
- コードの見通しが良くなる
- case文の条件をtypoしてもすぐにエラー個所がわからないが、ダックタイプにしておくと
no method error
ですぐに発見できる
もっと知りたい人は?
オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方
この本を読むことをお勧めします。
最初問題のあるプログラムからスタートして、それをダックタイプを用いてどうやってメンテナンス性が高いコードに改善していくかというストーリで学習できるのより理解が深まるかと思います。