Rubyのオブジェクト・メソッド・インスタンス・変数についてまとめてみた

## オブジェクトについて

### オブジェクトとは
Rubyにおいてはクラスから生成されたもののこと。

### クラスについて
Hogeクラス、のようなクラスを定義したとする。RubyではこのクラスもClassクラスに所属しているオブジェクトである、というのが大きなスタート。
これはどういうことかと言うと、HogeクラスというものがあったとするとこのHogeクラスも実際は`Class.new`して作られている、オブジェクトである、ということ。
下記の意味は`Hoge=Class.new`と同意義である。
```ruby
class Hoge
end
```

### インスタンスオブジェクト（インスタンス）
クラスから生成されるのがインスタンスオブジェクト（インスタンス）。
`クラス名.new`で生成することができる。
RailsにおけるモデルはClassクラスからインスタンスを生成し、定数を与えていると言える。
コントローラーも同様。

### レシーバーとは
~~メソッドの戻り値を受ける対象~~
~~下記の場合、Personがレシーバー。オブジェクトの世界ではオブジェクトにメッセージを送り、オブジェクトがメッセージを受け取る、と捉える。~~
メソッド呼び出しに関する概念でメソッドを呼び出す対象のオブジェクトのこと。←(@scivola様ご指摘ありがとうございます。)

具体例
`person = Person.new('たろう')`の部分においてはPerson クラスがレシーバー。
`person.put_receiver`の部分においてはローカル変数 person に代入されている Personオブジェクトがレシーバー。←(@scivola様ご指摘ありがとうございます。)
```ruby
class Person
  attr_accessor :name

  def initialize(name)
    @name = name
  end

  def greeting
    "私の名前は#{@name}です。"
  end

  def put_receiver
    puts self
    # selfでレシーバーを取得。言い換えれば、インスタンスメソッドの呼び出し元のオブジェクトを取得する
    # Pesrsonインスタンスオブジェクト自身を返す

    puts self.name
    # レシーバーのnameを取得
	# インスタンスオブジェクトに与えられたnameが返る
  end
end

person = Person.new('たろう')
person.put_receiver

```
出力結果
```bash
#<Person:0x00007fbae3908f08>
たろう
```

## メソッドの種類について

### クラスメソッド

そのクラス自身に関する情報の変更や参照の役割を持つ。
`self.xxx`で定義される。`クラス名.new`して生成したインスタンスからは呼び出せず、クラスオブジェクトからのみ呼び出せる。
```ruby
class Hoge
  def self.hoge
    puts "hoge"
  end
end
Hoge.hoge 
# => hoge
```

### クラスメソッドの使い所
例えば、5人分のPersonインスタンスを一気に生成するメソッドを定義したいとき、それはPersonクラスのクラスメソッドとして定義するのが適切。インスタンスメソッドとして定義してしまうと、個別のPersonインスタンスから他のPersonインスタンスを生成することになり不適切。

具体例
```ruby
class Person
  attr_accessor :name, :age

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

  def self.bulk_create(data)
    data.map { |d| Person.new(d[:name], d[:age]) }
  end
end

data = [
  {name: '太郎1', age: 10},
  {name: '太郎2', age: 20},
  {name: '太郎3', age: 30},
  {name: '太郎4', age: 40},
  {name: '太郎5', age: 50}
]

puts Person.bulk_create(data)
```
### インスタンスメソッド

個別に生成されたインスタンスに関する情報の変更や参照の役割を持つ。
クラスから生成されたインスタンスオブジェクトからしか呼び出せない。
```ruby
class Hoge
  def hoge
    puts "hoge"
  end
end
Hoge.new.hoge # => hoge
```

## 変数の種類について

### インスタンス変数
インスタンスごとに独立して持つ変数。変数の前に`@`をつけて定義する。
インスタンス変数にアクセスできるのはinitializeメソッドとインスタンスメソッドだけ。
initializeメソッドで初期化されて、その後各インスタンスメソッドから参照、変更される使い方が多い。
```ruby
class Foo
  # initializeメソッドで定義しinitializeメソッドからアクセスできる。
  def initialize
    @name = '太郎'
    p "#{@name} です"
  end

  # インスタンスメソッドからもアクセスできる
  def xxx
    p "#{@name} だぞ"
  end

  # クラスメソッドからはアクセスできない。
  def self.yyy
    p @name
  end
end
```
```ruby
foo = Foo.new 
# => '太郎です'

foo.xxx 
# => '太郎だぞ'

Foo.yyy 
# => nil
```

### クラス変数
そのクラス全てのインスタンスで共有される変数。
変数の前に`@@`をつけて定義される。
```ruby
class Hoge
  @@count = 0

  def xxx
    @@count += 1
    p @@count
  end

  def self.yyy
    @@count += 1
    p @@count
  end
end

hoge = Hoge.new

# 同じインスタンス内で値は共有される
hoge.xxx # => 1
hoge.xxx # => 2

# インスタンスが異なっても、同じクラスなので値は共有されている
hoge2 = Hoge.new
hoge2.xxx # => 3

# クラスメソッドからもアクセスできる。値も共有される。
hoge.yyy # => 4

```

### クラスインスタンス変数
変数名の前に`@`をつけて定義する。
※見た目はインスタンス変数と同じだが、定義する場所がクラス定義式内になる。
クラス変数とほぼ同じように使えるが、そのクラスのみでしか参照できない。
クラスメソッドからはアクセス可能。
**クラスオブジェクトのインスタンス変数である**ためインスタンスメソッドからアクセスすることはできない。
クラス定義式内で定義される（メソッド内で初期化されない）。
```ruby
class Hoge
  @class_instance = 'ハロー'

  def self.xxx
    p @class_instance
  end

  def yyy
    p @class_instance
  end
end

class Foo < Hoge
end

# クラスメソッドからクラスインスタンス変数は参照可能。
Hoge.xxx # => 'ハロー'

# インスタンス変数とみなされるため、インスタンスメソッドからクラスインスタンス変数は参照できない
hoge = Hoge.new
hoge.yyy # => nil

# 継承されたクラスからクラスインスタンス変数は参照できない
Foo.xxx # => nil
```

## 参考
https://qiita.com/digitter/items/6c232f0b07a0d78cd74f

https://qiita.com/tbpgr/items/56eb65c0ea5882abbb07

https://qiita.com/mogulla3/items/cd4d6e188c34c6819709