【Ruby】初学者向け－メソッドの基本について③

【Ruby】初学者向け－メソッドの基本について②においては
Procオブジェクトやyield、クラス定義について記載していました。

[https://qiita.com/y-kida/items/8fbbdedea8c7e7bd5530](url)


本記事ではその続きとして下記についてまとめていきます。

目次
・クラスメソッドについて
・クラス変数について
・クラスにおけるメソッド定義について
・破壊的メソッドについて

<h1>クラスメソッドについて</h1>

**クラスメソッド**
…クラスそのものに対して定義されるメソッドのこと。
 クラスからオブジェクトを生成せずにクラスに対してドット「.」をつけて呼び出すことができる。
　通常のメソッド（インスタンスメソッド）はクラスから生成されたオブジェクトに対して
 　使用されるが、クラスメソッドはクラス自体に適用される。
  オブジェクトをレシーバとする。
  （例）新たにインスタンスを作成するnewメソッドなど
  
------------------------------------------------------------

**クラスメソッドの定義方法**

```ruby:example_1.rb
class Test
    # 1つ目の定義方法。メソッド名の頭にselfをつけるとクラスメソッドになる（１つ）
    def self.first_method
        puts 'first'
    end

    # ２つ目の定義方法。class << selfとendの間にメソッドを記載するとクラスメソッドになる（複数）
    class << self
        def second_method
            puts 'second'
        end
        def third_method
            puts 'third'
        end
    end
end

# 各クラスメソッドの呼び出し方法
Test.first_method
Test.second_medhod
Test.third_method
```

-------------------------------------------------------------------------------
ただし、クラスメソッドはオブジェクトから呼び出すことはできない

```ruby:example_2.rb
# クラスメソッドの呼び出し方法を変更
Test.new.test
```

上記の呼び出し方で実行するとundifind_methodエラーが発生する。

-----------------------------------------------------------------------------

<h1>クラス変数について</h1>

**クラス変数**
…そのクラスのインスタンスで共有される変数のこと。
　クラス変数はクラス内で「@@変数名」の形で定義し、インスタンスメソッドからでも
 　クラスメソッドからでもアクセスできる。
  　異なるオブジェクトであっても同じクラスであれば値が共有される。

```ruby:example_2.rb
class Test2
    # クラス変数
    @@num = 1

    def increment
        @@num += 1
    end

    def decrement
        @@num -= 1 
    end

    def num
        puts @num
    end
    
    def self.num
        puts @num
    end
end

test = Test2.new
test.num
=> 1

test.increment
test.num
=> 2

bar = Num.new
bar.num
=> 2

bar.increment
bar.num
=> 3
bar.decrement
bar.num
=> 2
```
-----------------------------------------------------------------------------

<h1>クラスにおけるメソッド定義について</h1>

**publicメソッド**
…単純にクラス内に定義したメソッドはデフォルトでpublicメソッドとなる。
　オブジェクトから直にメソッドを呼び出すことができる。

**privateメソッド**
…オブジェクトから.記法で直接呼び出すことができないメソッド。
　「private」の記述の下に書く。
　クラス外部には公開されないメソッドで、クラス内のメソッドから呼び出して使用される。


```ruby:example_3.rb
    require 'date'

    class User
        attr_accessor :name, :birthday:

    def initialize(name, birthday)
        @name = name
        @birthday = birthday
    end

    # publicメソッド
    def display_birthday
        @birthday = strftime('%Y年 %m月% d日')
    end

    # publicメソッド
    def inner_call_display_birthday
        # selfは自身のオブジェクトを表している（self自体は省略可能）
        # 下記user変数に格納されたオブジェクトが「self」ということになる
        # 自身のオブジェクトをレシーバーとしてメソッドを呼び出している
        self.display_birthday

        # selfをつけない呼び出し方を「関数形式」と呼ぶ
        display_birthday
    end

    # privateメソッド呼び出し方法
    def call_private_name
        # selfをつけない呼び出し方を「関数形式」と呼ぶ
        private_name
    end

    private
    # privateメソッド
    def private_name
        @name
    end
end

birthday = Date.new(2000, 1, 1)
user = User.new('tarou', birthday)
puts user.display_birthday
puts user.inner_call_display_birthday

# privateメソッドを呼び出すときは、privateメソッドを呼び出すメソッドを呼び出す形式となる
# privateメソッドをそのまま呼び出すとエラーが発生する
puts user.call_private_name

```

---------------------------------------------------------------
<h1>破壊的メソッドについて</h1>

**破壊的メソッド**
…レシーバの値を変更するメソッドのこと。「メソッド名!」で表記する。


```ruby:example_4.rb
    str = 'string'
    => "string"
    
    str.upcase
    => "STRING"

    # 破壊的でないメソッドの場合は、変数strの中身が変化しない
    str
    => "string"

    # 破壊的メソッド
    str.upcase!
    => "STRING"

    # 破壊的メソッドの場合は、変数strの中身が変化する
    str
    => "STRING"
```
------------------------------------------------------------

真偽値を返すメソッドにも、破壊的メソッドと類似しているルールがある
以下、includeに?をつけて、真偽値を返すコードの例

```ruby:example_5.rb

    # cを含んでいるため真が返る
    %w[a b c].include?(c)
    => true

    # dを含んでいないため偽が返る
    %w[a b c].include?(d)
    => false
```

include以外にも「nil?」「present?」「blank?」等、「?」を使用して真偽値を返すものが存在する。