Rubyのselfってなんだ？

### 記事の対象
selfって何？
クラスメソッドって?
classやインスタンスはなんとなくわかる

### この記事で解説すること
- selfとは
- オブジェクトとは
- いろいろな場所でのself(クラス内・クラス外・インスタンスメソッド内・クラスメソッド内など)

### selfの一般的な説明
> selfはオブジェクトそのものである

と言われてもピンとこなかったんですよね。
ただ、腑に落ちた今は確かにそのとおりだなと思います。

### オブジェクトとは
まずオブジェクトについて理解していきましょう。
Rubyは全てがオブジェクトです。

- 文字列オブジェクト
- 数値オブジェクト
- 配列オブジェクト
- ハッシュオブジェクトなど

現実世界で言えば人やモノ、動物などありとあらゆるものをオブジェクトとして扱います。

### オブジェクトとインスタンスの違い
オブジェクトとインスタンスの違いは下記サイトでわかりやすく説明されていたので気になる方は読んでみてください。
一言で言うと
**クラスから生成されたオブジェクトのことをインスタンスと呼ぶ**
です。

[クラス・インスタンス・オブジェクトの違いは神の気分になるとわかる](https://freesworder.net/class-instance-object/)
### インスタンスの生成

`クラス名.new`

```ruby:インスタンスの生成
class Sample
end

p Sample.new #=> #<Sample:0x00007fe79b835240>
```
インスタンスが生成できました。

### selfについて
ここまではインスタンスやオブジェクトについてでしたが、ついにselfに片足を突っ込みます。
とりあえず適当にrbファイルを作って実行してみましょう。
もしくはターミナルでirbと打った後selfと打ってみましょう。
(Rubyをインストールしていないと使えません。ruby -vと打ってバージョン情報が出ないようならインストールされていないのでインストールしてください。)

```ruby:sample.rb
  p self
  #=> main
```
mainというものが出てきました。
mainとはなんでしょうか？

一言で言うと
**mainとはトップレベルに存在するインスタンスのことでObjectクラスのインスタンスです。**
難しいですね。

しっかり解説していきます。まずはObjectクラスからです。

### Objectクラス
Objectクラスとはクラスの実質的頂点(親)にいるクラスです。（実際にはもう一つ上のクラスが存在しますが、ここでは割愛します。）
クラスは階層構造になっていて文字列クラスなどの親クラスがObjectクラスになります。
(classメソッドで自身のクラス、superclassメソッドで親クラスを取得することができます。)


```ruby
p "文字列".class #=> String
p String.superclass #=> Object
```

### トップレベル

次にトップレベルですが、これはclass定義やmodule定義の外側のことを言います。
(moduleについては本記事では解説しません。制限が加わったclassのようなものと思っておいてください。)

```ruby:トップレベル
# ここから
#
#
#
# ここまでがトップレベル
class Sample
  # クラス内
end
# ここから
#
#
#
# ここまでもトップレベル
module SampleModule
  # モジュール内
end
# ここから
#
#
#
# ここまでもトップレベル
```

そしてターミナルでirbと打った時にいるのもトップレベルです。
ターミナルでirbと打つと
`irb(main):001:0>`
となります。
ここがトップレベルであり、そしてirbの後にmainとあることが確認できると思います。

またトップレベルでselfのクラスを確認してみると

```ruby
p self       #=> main
p self.class #=> Object
```

トップレベルのself(main)のクラスはObjectだということがわかります。

先ほどの発言に戻ると
`mainとはトップレベルに存在するインスタンスのことでObjectクラスのインスタンスです。`でした。
これは

トップレベルでのpメソッドの実行結果は`p self #=> main`だったこと。
そして`p self.class #=> Object`だったこと
そしてselfとはオブジェクト自身（インスタンス自身)を指すこと。

からもわかります。

トップレベルでいきなりpメソッドなどを実行できるのはmainがObjectクラスのインスタンスだからなんですね！
(ObjectクラスにはKernelモジュールがインクルードされているので実行できるというのが正確な答えだがここでは割愛)


### クラス内のself
次にクラス内のselfをみていきます。

```ruby:クラス内のself
class Sample
  p self #=> Sample
end
```

selfはオブジェクト自身のことでした。そのためクラス内ではそのクラスオブジェクト自身を表しています。

### インスタンスメソッド内のself

インスタンスメソッド内のselfはインスタンス自身(オブジェクト自身)を表しています。

```ruby:インスタンスメソッド内のself
class Sample
  def hoge
    p self
  end
end
sample = Sample.new
sample.hoge #=> #<Sample:0x00007f8524034f70>
```
ちなみにRubyはメソッドを呼び出す時、暗黙的にselfに対してメソッドを呼び出しています。(勝手にselfに対してメソッドを呼び出す。)

どういうことかというと

```ruby
class Person
  def greeting
    p self
    hello
  end

  def hello
    p "hello"
  end
end

person = Person.new
person.greeting #=> #<Person:0x00007f9937848a28>
                #=> "hello"
```

これと同じものが以下になります。

```ruby
class Person
  def greeting
    p self 
    self.hello
  end

  def hello
    p "hello"
  end
end

person = Person.new
person.greeting #=> #<Person:0x00007f9937848a28>
                #=> "hello"
```
どこが違うかお気づきでしょうか？
そうです。greetingメソッド内のhelloの呼び出しの前にself.がついています。
実はこのself.は付けても付けなくても同じ動きになるのです。
メソッドの呼び出しのたびにselfをつけるのは大変なのでこの仕様になっているのだと思います。

この時のgreetingメソッド内のselfはPersonクラスのインスタンス自身ですのでそのインスタンスに対してhelloメソッドが呼ばれているんですね。
(`greetingメソッド内のself.hello`と`トップレベルのperson.hello`は同じ結果になる。)

### クラスメソッドのself

クラスメソッド内のselfもオブジェクト自身を表しています。

```ruby:クラスメソッド内のself
class Person
  def self.greeting
    p self
  end
end

Person.greeting #=> Person
```
Personが返されています。

もちろんこのメソッド定義部分のselfもオブジェクト自身を表しているのですがメソッドの定義場所にあるselfってちょっと不思議な感じですよね。

```ruby
def self.greeting # ← このself
end
```

クラスメソッドとは特異メソッドの一つです。
では特異メソッドとは何か？

### 特異メソッド

特異メソッドはクラスとは関係なく個々のオブジェクト（インスタンス）に対してメソッドを定義します。

```ruby
morning = "good morning"
def morning.greeting
  p self
end

morning.greeting #=> "good morning"
```

これは何が起こっているのでしょうか？
まず`morning = "good morning"`でmorningという変数(オブジェクト)に"good morning"という文字列を代入しています。
その後morningオブジェクトに対してgreetingメソッドを定義しています。
greetingメソッド内ではpメソッドでselfを返しています。
この場合のselfは"good morning"という文字列オブジェクトなので
"good mornig"という文字列が出力されます。

この形が特異メソッドです。

クラスメソッド定義方法と同じですね。

```ruby:クラスメソッド定義 
class Person
  def self.greeting
  end
end
```

上のコードと見比べるとdef 〇〇.メソッド名のように定義方法が一緒ですね。
そしてこの時のselfはPersonだったので

```ruby:クラスメソッド定義
class Person
  def Person.greeting
  end
end
```
このようにも書けます。


### 最後に

いろいろなところでselfを使ってみました。
selfがオブジェクト自信を表すということが理解できれば幸いです。

やはり自分でコードを動かして検証していくと理解が高まりますね。
何かお気づきのことがありましたらコメント欄で教えていただけると助かります。

## 参考

[るびま](https://magazine.rubyist.net/articles/0046/0046-SingletonClassForBeginners.html)
http://i.loveruby.net/ja/rhg/book/minimum.html