Ruby.学習その5

#### 投稿目的
- 個人の学習目的で投稿していきます。
- Rubyの入門を読みながら自分なりの思考で記述しています。

#### 参考資料

[ゼロからわかる Ruby 超入門 (かんたんIT基礎講座)](https://www.amazon.co.jp/ゼロからわかる-Ruby-超入門-かんたんIT基礎講座-五十嵐/dp/4297101238/ref=sr_1_3?ie=UTF8&qid=1549614126&sr=8-3&keywords=ruby+入門)

## クラス
- クラスとはオブジェクトごとの違い、種類を決めてまとめている仕組みのことをクラスという。
- オブジェクトのクラスが分からない場合はclassメソッドを利用することで所属しているクラス名が返ってきます。

```ruby
p 100.class # Integer
p "クラス".class # String
p [1, 2, 3].class # Array
```

#### インスタンス
- クラスに属するオブジェクトをそのクラスのインスタンスであるともいいます。
- インスタンスとオブジェクトはほぼ同じ意味ですがクラスから作ったオブジェクトであり、そのクラスに属するという強調を持たせたのがインスタンス。

#### クラスでのメソッドの違い

- それぞれのオブジェクトは所属するクラスによって使用できるメソッドが違います。
- Integerクラスの整数オブジェクトの場合はeven?メソッドで偶数か判断するメソッドがあります。

```ruby
p 1.even? # false
p 2.even? # true
p 100.even? # true
```

- 上記で利用したIntegerクラスのeven?メソッドをStringクラスの文字列オブジェクトに利用しようとするとエラーが発生する。
- クラスが違うと利用できるメソッドなどは変わる。

```ruby
p 2.even? # true
p "クラス".even? # エラー
```

#### クラスとnewメソッド
- オブジェクトには2つの作り方が存在します、1つ目は今までやってきた下記のようなやり方です。

```ruby
p "String" # 文字列オブジェクト
p [1, 2, 3] # 配列オブジェクト
```

- 2つ目がクラスとnewを利用することでオブジェクト(インスタンス)作ることができます。
- Integerみたいにnewメソッドが存在しない場合もあります。
- Arrayのnewの引数の2は個数を表しています。
- オブジェクトを作成する際は2のやり方よりも1の方がよく使われます。

```ruby
p String.new # 空の文字列が作成
p String.new("クラス") # クラスという文字列が作成
p Array.new # 空の配列が作成
p Array.new(2, "クラス") # クラスという文字列を持った配列が2つ作成
```

#### クラスを作成
- クラスにはIntegerクラスやStringクラスなどがありますがクラスは自分で作成することもできます。
- クラスを作る事をクラスを定義するという。
- クラスを定義することで[こんな機能があったら]何て思った時に作成ができる。

```ruby
class クラス名
    内容
end
```

- 上記の用にクラスを定義するだけでは目に見える処理などは実行しても何も表示されません。
- しかし、クラスを定義しただけでもnewメソッド、classメソッドなどの基本的なメソッドは利用することができます。

```ruby
class Mac
end

hensuu = Mac.new # オブジェクトを作成して変数に代入
p hensuu.class # そのオブジェクトのクラスを表示、結果はMacと表示
```

#### クラス名
- クラス名付ける際は頭文字は大文字で2文字目以降小文字で2単語目以降は頭文字を大文字にすることで区切りを表します。
- このスタイルのことをキャメルケースと言います、camelは日本語でラクダで大文字がラクダのこぶのように見えるからです。
- 定数も大文字で入力しますが実はクラスの名前も定数です、クラスを定義するとクラス名の定数が作られます。

###### 補足: 実はクラスもオブジェクトです。

```ruby
class Mac
end

p Mac.class # class
```

#### クラスにメソッドを定義
- クラスに新しくメソッドを定義することができる。
- ゲームで例えるとクラスは種族、メソッドはその種族が使える魔法、オブジェクトはキャラクター的な感じな認識です。

```ruby
class クラス名
    def メソッド名
    end
end
```

##### クラスに定義したメソッドの呼び出し
- クラスに定義したメソッドを呼び出すにはクラスのオブジェクトを作成します
- その後はメソッドを利用するには[.メソッド名]で利用できるのでそう記述する。

```ruby
class Mac
    def state
        "起動"
    end
end

hensuu = Mac.new # オブジェクトを作成
puts hensuu.state # testメソッドが実行されおはようが返る
```

- メソッドを呼び出せるオブジェクトのことをレシーバという、上記の例でいうレシーバはMac.newが代入されているhensuuをレシーバといいます。

##### methodsメソッド
- metodsメソッドを利用するとレシーバであるオブジェクトで呼び出せるメソッドを一覧表示できる。

```ruby
p 1.methods.sort #　Integerクラスのオブジェクトの1に利用できるメソッドを昇順で表示します
```

- 上記で作成したMacクラスのオブジェクトも確認することもできます。
- 下記はMacクラスのオブジェクトが利用できるメソッドが表示されるのでstateメソッドも追加されています。
 
```ruby
class Mac
    def state
        "起動"
    end
end

hensuu = Mac.new
p hensuu.methods 
```

##### クラスに引数を受け取るメソッドを定義
- クラス内で定義するメソッドでも引数を持たせることもできます。

```ruby
class Mac
    def state(pc) # スリープを受け取り処理を実行して返す
        puts "#{pc}しています" 
    end
end

hensuu = Mac.new
hensuu.state("スリープ") # スリープをstateメソッドに渡す
```

##### クラスの中で同じクラス内のメソッドを呼び出す
- クラスには複数のメソッドを定義することができます。
- 同じクラス内のメソッドに別のメソッドを呼び出すこともできる。
- クラス内でメソッドを呼び出す時はレシーバを省略することができる。
- 省略した場合は実行中のメソッドのレシーバに対してメソッドを呼び出す。

```ruby
class Mac
    def state
       puts "起動" + stop # stopメソッドをstate内で利用
    end
    def stop
        "を停止"
    end
end
        
hensuu = Mac.new
hensuu.state 
```

##### selfメソッド
- 慣れるまではどのオブジェクトがレシーバなのか見分けるのが難しい場合にselfメソッドを利用します。
- selfメソッドを利用することでレシーバを調べることができる。

```ruby
class Mac
    def state
       p self # レシーバを表示する
       puts "起動" + stop 
    end
    def stop
        "を停止"
    end
end
        
hensuu = Mac.new
hensuu.state 
```

#### オブジェクトにデータを持たせる
- オブジェクトにデータを持たせることでデータに応じて異なる動作もできるようになるので幅が広がります。

##### インスタンス変数
- クラス内でメソッドを定義してその中に変数を定義するとその変数は同じクラス内であっても別のメソッド内でその変数を利用することはできない何故なら、ローカル変数は認識できる範囲が決まっているから。

```ruby
class Mac
    def state(pc)
        puts "#{pc}をしています"
        statepc =  pc # ローカル変数
    end
    def stop
        puts "#{statepc}を停止します"
    end
end

hensuu = Mac.new
hensuu.state("起動")
hensuu.stop # ここでname変数が定義されてないよとエラー
```

- そこで利用するのがインスタンス変数です、インスタンス変数はローカル変数よりスコープが広く同じオブジェクトであればメソッドをまたいで利用することができます。
- 変数名の前に@を記述することでインスタンス変数となる。
- newで作成されたオブジェクトがインスタンス変数の持ち主です。

```ruby
class Mac
    def state(pc)
        puts "#{pc}をしています"
        @statepc =  pc # インスタンス変数
    end
    def stop
        puts "#{@statepc}を停止します"
    end
end

hensuu = Mac.new # オブジェクトが作成されてインスタンス変数を持つ
hensuu.state("起動")
hensuu.stop
```

- 作成されたオブジェクトが別の場合は同じクラスに記述されているインスタンス変数でもオブジェクトが別ならインスタンス変数も別になる。

```ruby
class Mac
    def state(pc)
        puts "#{pc}をしています"
        @statepc =  pc # インスタンス変数
    end
    def stop
        puts "#{@statepc}を停止します"
    end
end

hensuu1 = Mac.new # オブジェクト1
hensuu2 = Mac.new # オブジェクト2

hensuu1.state("起動")
hensuu2.state("スリープ")

hensuu1.stop
hensuu2.stop
```

##### インスタンス変数を取得するメソッドを作る
- クラスの外でインスタンス変数を取得するには@変数名と記述しても取得はできません。
- 取得するには戻り値をインスタンス変数に設定したメソッドを定義する。
- インスタンス変数を取得するメソッド名は一般的に@を除いたインスタンス名をメソッド名にします。
- インスタンス変数は代入した際に作られる。

```ruby
class Mac
    def state(pc)
        puts "#{pc}をしています"
        @stop = pc
    end
    def stop # インスタンス変数が戻り値のメソッド
        @stop
    end
end

hensuu = Mac.new
hensuu.state("起動")
puts hensuu.stop     
```

- インスタンス変数を取得するメソッドができたので逆に代入するメソッドを作成
- インスタンス変数に代入するメソッド名は@変数名の@を除いて末尾に=を付けた名前にすることで直感的に代入すると分かりやすくなる。

```ruby
class Mac
    def stop=(pc) # インスタンス変数に代入するメソッド
        @stop = pc
    end
    def stop # インスタンス変数を取得するメソッド
        @stop
    end
end

hensuu = Mac.new
hensuu.stop = "停止"
puts hensuu.stop   
```

- instance_variablesメソッドを利用することでオブジェクトが持っているインスタンス変数の変数名一覧を取得することができる。

```ruby
class Mac
    def state(pc)
        @stop = pc
    end
end

hensuu = Mac.new
hensuu.state("起動")
p hensuu.instance_variables # 変数名一覧取得
```