8.5 リングのチェーン

`range`や`spread`のようなコンストラクタに加えて、別なリングの作成方法としては、作成済みのリングを操作する方法があります。

## チェーンコマンド

次のような単純なリングを作成します:

```
(ring 10, 20, 30, 40, 50)
```

リングを逆にしたいときにはどうしたらよいでしょう？リングを反転させるには、チェーンコマンドの`.reverse`を使います:

```
(ring 10, 20, 30, 40, 50).reverse  #=> (ring 50, 40, 30, 20, 10)
```

では次に、リングから最初の3つの値を取得するにはどうしたらよいでしょう？

```
(ring 10, 20, 30, 40, 50).take(3)  #=> (ring 10, 20, 30)
```

最後に、リングをシャッフルするにはどうしたらよいでしょう？

```
(ring 10, 20, 30, 40, 50).shuffle  #=> (ring 40, 30, 10, 50, 20)
```

## 多重チェーン

ここまでで既に強力なリングの作成方法を見てきましたが、
これらのコマンドを一緒に用いることで本当の力を発揮します。

リングをシャッフルし、最初の要素を削除し、次の3つの要素を得る場合にはどうでしょう？

段階的に見ていきましょう:

1. `(ring 10, 20, 30, 40, 50)` - リングの最初の状態
2. `(ring 10, 20, 30, 40, 50).shuffle` - シャッフルし - `(ring 40, 30, 10, 50, 20)`
3. `(ring 10, 20, 30, 40, 50).shuffle.drop(1)` - 最初の要素を削除し - `(ring 30, 10, 50, 20)`
4. `(ring 10, 20, 30, 40, 50).shuffle.drop(1).take(3)` - 3つの要素を得る - `(ring 30, 10, 50)`

*コマンドを一緒にくっつける*だけでこれらのコマンドの長いチェーンを作ることが分かったと思います。
チェーンコマンドを好きな順序で組み合わせることができ、それにより既に存在するリングから新しいリングを
生成するとても豊かで強力な方法を作り出しています。

## 不変性

リングは強力で重要な特徴を持っています。それは不変性と言って、リングを変更できないということを
意味しています。このセクションで紹介しているチェインコマンドが*リングを変更するのではなく*、
*新しいリングを作成*していることを意味しています。これにより、スレッドを跨いでリングを共有して、
同じリングを使っている他のスレッドに影響を与えないで、チェインを開始できることを意味しています。

## 利用可能なチェーンコマンド

ここに利用可能なチェーンコマンドを記載しておきます。

* `.reverse` - 逆順のリングを返却します
* `.sort`    - ソートされたリングを作成します
* `.shuffle` - シャッフルされたリングを作成します
* `.take(5)` - 最初の5つの要素をのみからなる新しいリングを返却します
* `.drop(3)` - 最初の3つの要素以外の要素からなる新しいリングを返却します
* `.butlast` - 最後の要素が欠けた状態の新しいリングをを返却します
* `.drop_last(3)` - 最後の3つの要素が欠けた状態の新しいリングをを返却します
* `.take_last(6)`- 最後の6つの要素をのみからなる新しいリングを返却します
* `.stretch(2)` - リングの個々の要素を2回ずつ繰り返します
* `.repeat(3)` - リング全体を3回繰り返します
* `.mirror` - 逆順のリングを自分自身に追加します
* `.reflect` - mirrorと同様ですが、真ん中の要素を重複させないようにします

数字を引数に取っているチェーンコマンドは、他の数字を取ることももちろん可能です。
最初の5個の要素を削除したい場合には、`.drop(3)`の代わりに遠慮無く`.drop(5)`を呼んでください。
