大ちゃんの駆け出し技術ブログ

RUNTEQ受講生のかわいいといわれるアウトプットブログ

【無職に転生 ~ 就職するまで毎日ブログ出す_13】【Ruby】Enumerable

はじめに

こんにちは、大ちゃんの駆け出し技術ブログです。

タイトルにあるとおり【無職に転生 ~ 就職するまで毎日ブログ出す】というチャレンジをしています!!!!昨日までは就活するまで本気出すでしたが、これだとまるで就活後は頑張らないのかと思われてしまいそうで、、、大人気アニメのタイトルのまるパクリチャレンジです。

https://i.gyazo.com/3a02b7aae4e5e538130d4bb199b55dc7.png

RailsやらRubyやらSQLやらその他Webの知識やらが色々と抜け落ちているのを感じており、知識の定着のためにもアウトプットする機会を増やすためです。加えて、退職して文字通り無職に転生しましてプロニートになり、毎日時間に余裕ができたので引き締めるためにも毎日投稿を思い至りました!

【投稿内容】

  • SQLの難しい処理 (副問合せ、JOINとか複雑な処理が書けない)
  • Rails全般 (純粋に必要な知識が多すぎる、網羅的な理解が足りない)
  • Rubyのあまり使わないメソッドや記述方法 (あまり重要ではないけど特に)
  • Web知識全般 (クッキーやら、セッションやらなんとなくで理解しているものの自分の言葉で説明できない)
  • 書籍 (スタートアップ企業に勤めるので、自分が会社に与える影響やパフォーマンスを高めるためビジネス書を読んでいきます。)

本日やること

本日はEnumerableについて解説します。Arrayクラスや昨日までのHashクラスの勉強をした時に以下のように継承しているメソッド欄に常にEnumerableがありました。

https://i.gyazo.com/226cc85c623affa4974065c76f919aa1.png

気になったので調べてたのでここに記載しておきます。なお、調べる量がほとんどなかったので今回の記事はかなり短くなると思います。

Enumerableとは

Enumerableとは一体何なのか?その回答が公式のRubyリファレンスマニュアルに載っていたので引用します。

繰り返しを行なうクラスのための Mix-in。このモジュールのメソッドは全て each を用いて定義されているので、インクルードするクラスには each が定義されていなければなりません。 ArrayHashRangeEnumerator等のクラスで、 Enumerableモジュールはインクルードされています。ただし、効率化のため、そのクラスでEnumerableと同名・同等の機能を再定義(オーバーライド)しているケースも少なくなく、特にArrayクラスでは同名のメソッドを再定義していることが多いです。

module Enumerable

"繰り返しを行なうクラスのための Mix-in(ミックスイン)"とあります。ミックスインとはクラスにincludeモジュール名(or extend モジュール名)でモジュールにあるメソッドを取り込むことを指します。例えば、以下のようにモジュールが定義されていれば、

module Hoge
    def foo
    p 'foo'
  end
end

下記のようにミック心の記述を書くことでモジュールに定義されているメソッドが使用できます。

class Animal
    include Hoge
end

animal = Animal.new
animal.foo # => 'foo'

つまり、Enumerableとはモジュールのことだったのです。そしてArrayHashRangeEnumerator等のクラスにミックスインされているということですね。

Enumerableモジュールで定義されているメソッドは以下のようになります。

https://i.gyazo.com/be9b530804fc54f24c488a017806481a.png

そしてこれらはすべてeachメソッドを用いて定義されているらしいです。eachメソッド自体はEnumerableモジュールで定義されていないので、ミックスインするクラスには必ずeachメソッドが定義されている必要があります。eachメソッドが定義されているクラスとしてArrayHashRangeEnumeratorのクラスは該当するということです。

また、Enumerableモジュールで定義されているメソッドがミックスインされるクラスにも定義されていることがあるらしいですね。引用元ではArrayクラスで定義されているメソッドが重複していることが多いそうです。リファレンスを参照すると確かに多くの同名メソッドが定義されていました。

class Array

まだ確証はありませんが、オーバーライドされないEnumerableモジュールのメソッドはおそらくArrayクラスと重複していないメソッドになるでしょう。

https://i.gyazo.com/01a21aacd18ece0356058b2f14762b96.png

これらを把握すれば大体Enumerbleモジュールのメソッドは覚えられているのかなと思います。

Rangeクラス、Enumeratorクラス

上述したことでEnumerableの説明は終わりです。流石にこれだけだとあまりにも短いと思ったので、EnumeratorがミックスインされるクラスとしてArrayとHashはわかるのですが、RangeとEnumeratorについてはあまりピンとこなかったので確認しておきます。

Rangeクラス

class Range

範囲オブジェクトのクラス。範囲オブジェクトは文字どおり何らかの意味での範囲を表します。数の範囲はもちろん、日付の範囲や、「"a" から "z" まで」といった文字列の範囲を表すこともできます。

この範囲オブジェクトのクラスについてはよく使うことも多いかなと思います。

(1..3)
=> 1..3

これは普段何気なく使っていましたがRangeクラスというオブジェクトのインスタンスなんですね。classメソッドでクラスが確認できます。

(1..3).class
=> Range

この範囲オブジェクトはRangeクラスを用いでインスタンス化もできます。

Range.new(1, 5)
=> 1..5

基本的には繰り返し処理などで使われるケースが多そうです。

Range.new(1, 5).each {|n| puts n}
# 出力
1
2
3
4
5

Rangeクラスについてはかなり内容が濃いので別の記事でまたアウトプットしたいです。

Enumeratorクラス

each 以外のメソッドにも Enumerable の機能を提供するためのラッパークラスです。また、外部イテレータとしても使えます。 (中略) Enumerator を生成するには Enumerator.newあるいは Object#to_enumObject#enum_for を利用します。また、一部のイテレータはブロックを渡さずに呼び出すと繰り返しを実行する代わりに enumerator を生成して返します。

このクラスについてはあまりよくわからなかったのですが下のような使い方をするそうです。下記のような使い方が外部イテレーターと言います。

authors = Enumerator.new do |y|
  y << '村上春樹'
  y << '吉本ばなな'
  y << '小川洋子'
end

authors.next
=> "村上春樹"
authors.next
=> "吉本ばなな"
authors.next
=> "小川洋子

Ruby の Enumerator とたわむれる | Engineers' Blog

終わりに

この間JQueryの記事を書くと言ったのですが今日はこの記事の内容にしました。 今回だいぶ内容が薄くてすみません💦 次の記事ではJQueryについて書こうと思います。