・オープンクラスって何?
・モンキーパッチって何?
・2つの違いは何?
結論から言うと、オープンクラスとモンキーパッチは同じ技術です。
オープンクラスはどんな技術なのか?
なぜ、オープンクラスがモンキーパッチと呼ばれるのか?
以上についてまとめていきます。
興味ある方はご一緒にどうぞ。ではスタートします!
オープンクラス
オープンクラスとは既存のクラスを修正する技術です。
例えば以下のようなクラスがあったとします。
class A
def test
puts 'testだよ'
end
end
クラスAに対して追加でメソッドを追加したい場合はよくあることだと思います。
直接、既存のソースを修正する方法もあるのですがRubyでは以下のような書き方もあります。
class A def test
puts 'testだよ'
end
end
class A
def superTest
puts 'すごいtestだよ'
end
end
クラスAを2回定義しているように見えますが、Rubyの場合は違います。
Rubyはクラスが存在しなければクラスを定義しますが、存在している場合は既存のクラスを再オープンしてメソッドを追加します。
オープンクラスの主な使用方法
ライブラリなどに、独自メソッドを追加したいなんて時に使えます。
ライブラリのクラスを再オープンして、その中に独自メソッドを記載します。
上の例ではパッとしませんでしたが、ライブラリを自分の好きなようにカスタマイズできると考えるとかなり強力な技術だと思いませんか?
モンキーパッチ
強力なオープンクラスですが、別名があります。
それが、モンキーパッチです。
オープンクラスの主な使い方として、「ライブラリなどに独自メソッドを追加」したい場合に使えるよと書きましが、ライブラリだけでなく標準ライブラリも対象にすることができます。
つまり、Stringクラスなんかも無理やり上書き更新できてしまうと言うことです。
例えば、Stringクラスの文字列の長さをはかるlengthメソッド。
puts "abc".length #> 3
通常であればこうです。
しかし、lenghtメソッドを知らない人がオープンクラスを使って書き換えた場合は?
class String
def length
puts '何やってんの!?'
end
end
puts "abc".length #> 何やっての!?
はい、無理やり変えることが出来てしまいます。
既存の影響を何も考えずにこう言うことをしてしまうとバグの元です。
こうしたクラスへ対して何も考えずに修正入れてしまうのがよくないと考えた人たちがこのようなコードに対してモンキーパッチと呼ぶようになったわけです。
どうやってモンキーパッチを防ぐ?
対処方法は2つあります。
1つは、クラスを調べて同じようなメソッドがないか?誤って上書き更新しないようにすることです。
instance_methods()などのメソッドを使えば確認できます。
もう1つは、Refinementsと言う仕組みを使ってオープンクラスの適用箇所を限定的にすることです。
クラスBの中だけ独自メソッドに書き換えるーとか。
両方使えばだいぶモンキーパッチになるリスクを防げると思います。
、、、がまずは本当にオープンクラスじゃないとダメ?ってところから検討するのがベストかもしれませんねw
まとめ
・オープンクラスは、既存ライブラリを自分の好きなようにカスタマイズできる強力な技術
・強力な反面、バグの元になりかねない・・・
・使う際は慎重に!対象方法は2つ!(1)既に同じメソッドがないか調査すること(2)Refinementsを使って適用箇所を限定的にする