【翻訳】あまり知られてないけど便利なRubyのメソッド7選

Ruby学習の一環として、週に1度Ruby関連のブログ記事(英語)を翻訳しています。
今回は便利なメソッド集。

原文：[7 Little-Known Ruby Methods To Help You Write Better Code](http://www.rubyguides.com/2017/10/7-powerful-ruby-methods/)

↓以下本文↓

-------------------------
Rubyのメソッドを正しく使えば、もっと楽になるって知ってました？
より多くのメソッドを知れば知るほど、より良いコードをより速く書くことができるようになります(パフォーマンス/クオリティ両方の面で)。
というわけで、今日はあまり知られていない便利なメソッドを7つ紹介したいと思います。

# `Integer#digits` メソッド(Ruby 2.4)

これはRuby 2.4から導入されたメソッドで、数字の各桁を取り出したい時に便利です。
注：Ruby2.4をまだよく知らない方へ。2.4では`Fixnum`と`Bignum`は`Integer`に吸収されました。

数字を配列のように扱って要素が指定できそうな気がするかもしれません。

```rb
2[0]
# 0
2[1]
# 1
```

しかし実際には桁の値ではなく、2進数に変換した場合のビットの値が返ってきます。
なので、`digits`メソッドが登場するまでのよくある解決方法は、数字を文字列に変換し、charsメソッドを使って配列に入れて、そして最後に文字列を数字に再度変換する、というものでした。

#### 【例】

```rb
123.to_s.chars.map(&:to_i).reverse

[3, 2, 1]
```
しかし、digitsメソッドが登場したことで、こう書くだけでよくなりました。

```rb
123.digits

[3, 2, 1]
```

こちらの方がずっといいですよね。

# Tapメソッド

オブジェクトを生成して、メソッドをいくつか呼び出した後に同じオブジェクトを返したい時ってありますよね。

こう書かざるを得ないでしょうかね。

```rb
user = User.new
user.name = "John"
user
```

問題は、この一時変数をどう扱えば良いのかということ。
こんな時こそ `tap` メソッドの出番です！
`tap` メソッドを使うとこんな風に書けます。

```rb
User.new.tap { |user| user.name = "John" }
```

これで一時変数を使わずにすみます。やったね！

# `Array#values_at`

配列もしくはハッシュから不連続の複数の値を取り出したい時はこう書いているかもしれません。

```rb
arr = [1,2,3,4,5]
a, b, c = arr[0], arr[1], arr[4]
```

これが、`values_at`メソッドを使うとこのように書けます。

```rb
arr = [1,2,3,4,5]
a, b, c = arr.values_at(0, 1, 4)
```

ハッシュに使うこともできます。

```rb
hash = {bacon: 300, chocolate: 200}
p hash.values_at(:bacon, :chocolate)
# [300, 200]
```

# `Hash#transform_values`(Ruby 2.4)

何らかの事情により、ハッシュの全ての値を変更したいとしましょう。
そんな時は`Array#map`を使う人が多いんじゃないかと思います。

`map`の問題は、ハッシュの代わりに配列の配列(多次元の配列)が返ってきてしまうという点。ここでは`Hash#map`が使えます！

なので解決策の一つは、こうですね。

```rb
h = {bacon: 200, coconut: 300}
h.each { |k, v| h[k] = v*2 }
```

今回の例では、それぞれの値に2をかけています。

結果はこう。

```rb
{:bacon=>400, :coconut=>600}
```

でもRuby2.4以降なら、もっといい方法があります。

```rb
h.transform_values! { |v| v * 2 }
```

これはもともとRailsで使われていたメソッドで、今ではRailsのフレームワーク外でも使えるようになりました:)

# `Kernel#itself` (Ruby2.2)

もし、一見あまりパッとしたメソッドに見えないなと思ったとしたら、私も同意見です。

でもまあいくつか便利な例を見てみてください。

例えば単語の繰り返しを含む配列があり、その回数を数えたいとしましょう。

やり方は色々ありますが、このケースは`Kernel#itself`を試すのにぴったりです。

#### 【例】

```rb
words = %w(cat cat tiger dog cat)
words.group_by(&:itself).transform_values(&:size)
Hash#transform_values!と組み合わせていることもお忘れなく！
```

もし`transform_values`が使えなければ、こう書くこともできます。

```rb
words
  .group_by(&:itself)
  .each_with_object({}) { |(k,v), hash| hash[k] = v.size }
```

# `Array#count`
ただ数えたいだけのときってありますよね。

いつもの`counter + loop`の代わりに、`count`メソッドが使えます！

#### 【例】

```rb
letters = %w(a a a b c d a)
letters.count("a")
# 4
```

配列の場合はブロックも引数に取ることができるので、もっと複雑なこともできます。

```rb
numbers = [1,2,3,4,5,6]
numbers.count(&:even?)
# 3
```

# `Enumerable#cycle`
なんらかのパターンを繰り返したい？もしくはシンプルにon/offを切り替えたい？
なら、`Enumerable#cycle`がぴったりです！

#### 【例】

```rb
array = %w(a b c)

# Same as array * 3
array.cycle(3).to_a
```

私の場合は、「スイッチ」や「切り替え(toggle)」オブジェクトを生成する時に重宝しています。

```rb
switch = %w(on off).cycle
switch.next
```

「スイッチ」の値を変更する際に現在の値を確認する必要がない、というのがこのメソッドの便利なところですね。nextを呼び出せば、Rubyが自動的に次の値を判断してくれます🙂

# まとめ

さて、今回は以下のメソッドを紹介しました
`Integer#digits`, `Kernel#tap`, `Array#values_at`, `Hash#transform_values`, `Kernel#itself`, `Array#count`, `Enumerable#cycle`.

もし既にご存知でしたら素晴らしい！もし知らなかったのであれば、便利だと思ってもらえれば幸いです🙂