0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

オープンクラス、モンキーパッチ

Posted at

定義済のクラスを継承して独自クラスを定義できる

irb(main):001* class MyString < String
irb(main):002> end
=> nil
irb(main):003> s = MyString.new("Hello")
=> "Hello"
irb(main):004> s
=> "Hello"
irb(main):005> s.class
=> MyString
irb(main):006* class MyArray < Array
irb(main):007> end
=> nil
irb(main):008> a = MyArray.new()
=> []
irb(main):009> a << 1
=> [1]
irb(main):010> a << 2
=> [1, 2]
irb(main):011> a
=> [1, 2]
irb(main):012> a.class
=> MyArray

オープンクラスは定義済のクラスにも再定義できる

Rubyのクラスは変更に対してオープンなので、「オープンクラス」と呼びれています。

irb(main):013* class String
irb(main):014*   def shuffle
irb(main):015*     chars.shuffle.join
irb(main):016*   end
irb(main):017> end
=> :shuffle
irb(main):018> s = 'Hello, I am Alice'
=> "Hello, I am Alice"
irb(main):019> s.shuffle
=> "llclo mieeIHA, a "
irb(main):020>
irb(main):021> s.shuffle
=> "eaI ,Aoe mlliHlc "

Rails独自のメソッドがある

garden(dev)> 'MyString'.underscore
=> "my_string"
garden(dev)> numbers = [1, 2, 3]
=> [1, 2, 3]
garden(dev)> 2.in?(numbers)
=> true
garden(dev)> 5.in?(numbers)
=> false

モンキーパッチとは既存の実装に上書きして、自分が期待する挙動に変更すること

irb(main):023* class User
irb(main):024*   def initialize(name)
irb(main):025*     @name = name
irb(main):026*   end
irb(main):027*
irb(main):028*   def hello
irb(main):029*     "Hello, #{@name}"
irb(main):030*   end
irb(main):031> end
=> :hello
irb(main):032> user = User.new("Alice")
=> #<User:0x00000001071985e0 @name="Alice">
irb(main):033> user.hello
=> "Hello, Alice"
irb(main):034* class User
irb(main):035*   def hello # ←既存の実装の上書きを行ってる
irb(main):036*     "#{@name}さん,こんにちは!"
irb(main):037*   end
irb(main):038> end
=> :hello
irb(main):039> user.hello
=> "Aliceさん,こんにちは!

エイリアスメソッドにして再利用する

irb(main):001* class User
irb(main):002*   def initialize(name)
irb(main):003*     @name = name
irb(main):004*   end
irb(main):005*
irb(main):006*   def hello
irb(main):007*     "Hello, #{@name}!"
irb(main):008*   end
irb(main):009> end
=> :hello
irb(main):010* class User
irb(main):011*   alias hello_original hello
irb(main):012*
irb(main):013*   def hello
irb(main):014*     "#{hello_original}じゃなくて、#{@name}さん、こんにちは!"
irb(main):015*   end
irb(main):016> end
=> :hello
irb(main):017> user = User.new("Alice")
=> #<User:0x000000010c02ccb0 @name="Alice">
irb(main):018> user.hello
=> "Hello, Alice!じゃなくて、Aliceさん、こんにちは!"

以下に注意

オープンクラスやモンキーパッチは非常に強力で上手く使えば開発の効率を高めることができます。

オープンクラスやモンキーパッチを乱用してはいけません。最初に検討すべきことは、オープンクラスやモンキーパッチに頼らずに要件を満たすコードを書けないか、ということです。

感想

確かにこの機能はすごいが失敗をするとめんどくさい展開になりそうだ

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?