Ruby のトップレベルメソッドって結局なんなの

[ブログ記事](http://secret-garden.hatenablog.com/entry/2019/02/19/000318)からの転載です。


以下のような質問があったのでちょっと解説。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/pink_bangbi?ref_src=twsrc%5Etfw">@pink_bangbi</a> <br>僕はselfの概念がつかめておらず、バンビさんが以前書かれた記事で４つ目と5つ目（■）の項目の意味が理解できませんでした。  暇な時で構いませんので解説をいただきたいです。   <a href="https://t.co/ZgX3UQ6bjj">pic.twitter.com/ZgX3UQ6bjj</a></p>&mdash; あつき (@atsuki09130) <a href="https://twitter.com/atsuki09130/status/1097495504877801473?ref_src=twsrc%5Etfw">2019年2月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


トップレベルメソッドを理解するためには、以下の3つの Ruby の機能について理解する必要があります。

* `self`
* トップレベル
* `Object` クラス


## `self` ってなに

まず、トップレベルメソッドを理解する前に『 `self` とは何か』を知る必要があります。
`self` とはメソッド内で『メソッドを呼び出したレシーバ』を参照するキーワードになります。
また、レシーバとは『メソッド呼び出しの左辺のオブジェクト』を指します。

```ruby
class X
 def foo
  "foo"
 end

 def hoge
  # meth を呼び出したレシーバを参照する
  pp self
  # => #<X:0x00005627e8a8a050>

  # レシーバ、つまり x の foo メソッドを呼び出す
  pp self.foo
  # => "foo"
 end
end

x = X.new

# メソッドを呼び出す際に左辺にあるオブジェクトの事を『レシーバ』という
# この場合は x オブジェクトがレシーバに該当する
x.hoge
```

また、レシーバをつけずにメソッドを呼び出した場合は暗黙的に『`self` をレシーバとして』メソッドを呼び出します。

```ruby
class X
 def foo
  "foo"
 end

 def hoge
  # レシーバがなければ self のメソッドを呼び出す
  # self.foo と等価
  pp foo
  # => "foo"
 end
end
```


## トップレベルって？

そもそも『Ruby のトップレベルって何？』っていう話なんですが、Ruby では『`class` や `module` の中で定義していないメソッド』がトップレベルメソッドに該当します。

```ruby
# class や module 内で定義していないメソッド
def topleve_method
 "topleve_method"
end

class X
 # これは X のインスタンスメソッドなのでトップレベルではない
 def meth

 end
end
```

また、トップレベルでも `self` は存在し、トップレベルで `self` を呼び出した場合、 `main` という名前のオブジェクトを返します。

```ruby
pp self
# => main
```

`main` はトップレベルで定義されている特別なオブジェクトになります。


## トップレベルでメソッドを定義するとどうなるの？

トップレベルでメソッドを定義した場合、暗黙的に『`Object` クラスの `private` メソッド』として定義されます。
どういうことかというと

```ruby
def hoge
 "hoge"
end
```

というトップレベルメソッドは、

```ruby
class Object
 private
 def hoge
  "hoge"
 end
end
```

という定義と等価になります。
ちなみに Ruby における `private` とは『レシーバをつけて呼び出すことが出来ないメソッド』になります。

```ruby
class X
 # hoge を private メソッドとして定義する
 private
 def hoge
 end

 def foo
  # OK : レシーバをつけずに呼び出す
  hoge

  # NG : self もつけて呼び出すことは出いない
  self.hoge
 end
end

x = X.new

# NG : レシーバをつけて呼び出すことは出来ない
x.hoge
```


## `Object` クラスって何

`Object` クラスは『全てのクラス』が継承しているクラスになります。
例えば `String` や `Array` といった組み込みクラスやユーザが定義したクラスも暗黙的に `Object` クラスを継承しています。

```ruby
# Module#< で任意のクラスを継承しているかチェックする

# 組み込みクラスは Object を継承している
p String < Object
p Array < Object

# ユーザが定義したクラスも暗黙的に Object を継承している
class X
end
p X < Object
```

つまり 『トップレベル定義したメソッド＝ `Object` クラスの `private` メソッド』は『 `Object` を継承しているクラス＝全てのクラス』の『`private` メソッド』として参照できます。

```ruby
# Object の private メソッドとして定義される
def hoge
 "hoge"
end

class X
 def foo
  # Object は親クラスなので
  # 親クラスの private メソッドが呼べる
  hoge
 end
end

x = X.new
p x.foo
# => "hoge"

# NG : private メソッドなので直接呼べない
# p "foo".hoge

# OK : send だと private メソッドも明示的に呼べる
p "foo".send(:hoge)
# => "hoge"
```


## 結局トップレベルでメソッドって？

* トップレベルでメソッドを定義すると Object のメソッドとして定義される
* Object は全てのクラスが継承しているのでどのクラスからでも呼び出せる
* 当然トップレベルの `self`（= `main`）も `Object` クラスを継承しているのでトップレベルでも呼び出せる
* `main` とトップレベルメソッドは特に関連はない

トップレベルの `self` が `main` っていう特別なオブジェクトなので、どうしてもそっちの方に意識が向くんですが、トップレベルの `self` とトップレベルのメソッドは特に関連性はありません。
まずは、『トップレベルメソッド』というのが先にあり、『`main`』っていうのが後にあります。
ちなみに『トップレベルメソッド』の他に『トップレベル定数』というものがありトップレベル定数はトップレベルメソッドの100000万倍ぐらいややこしい仕様なので知らないほうがいいです。