Enumerator::LazyはEnumerable#injectを使用できる


Enumerator::Lazyの継承関係を理解できていませんでした。。
以下にまとめました。

# ①Enumerator::Lazy#takeで指定した数のEnumerator::Lazyオブジェクトを取得

```rb:①
p (1..Float::INFINITY).lazy.map { |i| i ** 2}.take(3)
# =>#<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: 1..Infinity>:map>:take(3)>
```

# ②Enumerator::Lazy#forceで配列を取得
```rb:②
p (1..Float::INFINITY).lazy.map { |i| i ** 2}.take(3).force
# =>[1, 4, 9]
```

# ③配列に対してEnumerable#injectの実行
```rb:③
p (1..Float::INFINITY).lazy.map { |i| i ** 2}.take(3).force.inject(0,&:+)
# => 14
```
# ④Enumerator::Lazyに対してEnumerable#injectの実行
③と同じ結果。`Enumerator::Lazy#force`は不要であると分かる。

```rb:④
p (1..Float::INFINITY).lazy.map { |i| i ** 2}.take(3).inject(0,&:+)
# => 14
```

# まとめ
Enumerator::Lazyオブジェクトに対してinjectメソッドを呼ぶと例外が発生するかと思っていましたが間違いでした。
Enumerator::Lazy#forceで配列に戻してからでないと、injectメソッドを使用することができないと思っていましたがそんなことはなく、Enumerator::LazyはEnumerableモジュールを継承しているので、配列に戻さなくてもそのままEnumerable#injectを使用できました。


# 参考リンク
## instance method Enumerator::Lazy#take
http://docs.ruby-lang.org/ja/2.1.0/method/Enumerator=3a=3aLazy/i/take.html

`take(n) -> Enumerator::Lazy`

>
Enumerable#take と同じですが、**配列ではなくEnumerator::Lazy を返します。**
n が大きな数 (100000とか) の場合に備えて再定義されています。 配列が必要な場合は Enumerable#first を使って下さい。  
[PARAM] n:
要素数を指定します。
[EXCEPTION] ArgumentError:
n に負の数を指定した場合に発生します。
[SEE_ALSO] Enumerable#take
>


## instance method Enumerator::Lazy#force
http://docs.ruby-lang.org/ja/2.1.0/method/Enumerator=3a=3aLazy/i/force.html

`force(*args) -> [object]`

>
全ての要素を含む配列を返します。Lazy から実際に値を取り出すのに使います。
`Enumerable#to_a` のエイリアスです。
>


## instance method Enumerable#inject
http://rurema.clear-code.com/2.1.0/method/Enumerable/i/inject.html

以下の通り、`Enumerator::Lazy`は`Enumerableモジュール`を継承しているので`Enumerable#inject`を使用できる。

```rb
pry(main)> Enumerator::Lazy.ancestors
=> [Enumerator::Lazy, Enumerator, Enumerable, Object, PP::ObjectMixin, Kernel, BasicObject]
```

![クラスの継承関係](https://qiita-image-store.s3.amazonaws.com/0/17718/855fb521-75c0-8a12-a4c1-c1835d096a6e.png)

>引用元：
[クラスの継承関係](http://qiita.com/gam0022/items/8acfc0c674b96060c03f#2-4)
[EnumeratorとEnumerator::Lazyの違い](http://qiita.com/gam0022/items/8acfc0c674b96060c03f#2-4)
>

# 参考にしたツイート
以下のツイートにインスパイアされて記事を書きました。
参考： [武田哲也さんのRuby技術者認定試験受験記](http://togetter.com/li/769555)


<blockquote class="twitter-tweet" data-conversation="none" lang="ja"><p><a href="https://twitter.com/hashtag/RubyGold?src=hash">#RubyGold</a>&#10;こんな感じのコードが出た。結果どうなる？と。&#10;(1..Float::INFINITY).lazy.map {|i| i**2 }.take(3).inject(0) {|sum,i| sum += i }</p>&mdash; 武田哲也 (@__takeda) <a href="https://twitter.com/__takeda/status/554073875084877824">2015, 1月 11</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-conversation="none" lang="ja"><p><a href="https://twitter.com/hashtag/RubyGold?src=hash">#RubyGold</a>&#10;（続き）lazy も take も初めて見たが、lazyは遅延評価的なやつかな、やりたいのは「1～3の冪乗の合計」だろう、1+4+9=14 →正解。&#10;これらはRuby2.0で導入された。&#10;<a href="http://t.co/NhDysp1LQM">http://t.co/NhDysp1LQM</a></p>&mdash; 武田哲也 (@__takeda) <a href="https://twitter.com/__takeda/status/554073972736659456">2015, 1月 11</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

>
補足： Enumerator::Lazy は2.0からですが、 Enumerable#take は1.8.7から入っています。
http://ref.xaio.jp/ruby/classes/enumerable/take
>