定義済のクラスを継承して独自クラスを定義できる
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さん、こんにちは!"
以下に注意
オープンクラスやモンキーパッチは非常に強力で上手く使えば開発の効率を高めることができます。
オープンクラスやモンキーパッチを乱用してはいけません。
最初に検討すべきことは、オープンクラスやモンキーパッチに頼らずに要件を満たすコードを書けないか
、ということです。
感想
確かにこの機能はすごいが失敗をするとめんどくさい展開になりそうだ