Ruby学習の一環として、週に1度Ruby関連のブログ記事(英語)を翻訳しています。
今回は便利なメソッド集。
原文:7 Little-Known Ruby Methods To Help You Write Better Code
↓以下本文↓
Rubyのメソッドを正しく使えば、もっと楽になるって知ってました?
より多くのメソッドを知れば知るほど、より良いコードをより速く書くことができるようになります(パフォーマンス/クオリティ両方の面で)。
というわけで、今日はあまり知られていない便利なメソッドを7つ紹介したいと思います。
Integer#digits
メソッド(Ruby 2.4)
これはRuby 2.4から導入されたメソッドで、数字の各桁を取り出したい時に便利です。
注:Ruby2.4をまだよく知らない方へ。2.4ではFixnum
とBignum
はInteger
に吸収されました。
数字を配列のように扱って要素が指定できそうな気がするかもしれません。
2[0]
# 0
2[1]
# 1
しかし実際には桁の値ではなく、2進数に変換した場合のビットの値が返ってきます。
なので、digits
メソッドが登場するまでのよくある解決方法は、数字を文字列に変換し、charsメソッドを使って配列に入れて、そして最後に文字列を数字に再度変換する、というものでした。
【例】
123.to_s.chars.map(&:to_i).reverse
[3, 2, 1]
しかし、digitsメソッドが登場したことで、こう書くだけでよくなりました。
123.digits
[3, 2, 1]
こちらの方がずっといいですよね。
Tapメソッド
オブジェクトを生成して、メソッドをいくつか呼び出した後に同じオブジェクトを返したい時ってありますよね。
こう書かざるを得ないでしょうかね。
user = User.new
user.name = "John"
user
問題は、この一時変数をどう扱えば良いのかということ。
こんな時こそ tap
メソッドの出番です!
tap
メソッドを使うとこんな風に書けます。
User.new.tap { |user| user.name = "John" }
これで一時変数を使わずにすみます。やったね!
Array#values_at
配列もしくはハッシュから不連続の複数の値を取り出したい時はこう書いているかもしれません。
arr = [1,2,3,4,5]
a, b, c = arr[0], arr[1], arr[4]
これが、values_at
メソッドを使うとこのように書けます。
arr = [1,2,3,4,5]
a, b, c = arr.values_at(0, 1, 4)
ハッシュに使うこともできます。
hash = {bacon: 300, chocolate: 200}
p hash.values_at(:bacon, :chocolate)
# [300, 200]
Hash#transform_values
(Ruby 2.4)
何らかの事情により、ハッシュの全ての値を変更したいとしましょう。
そんな時はArray#map
を使う人が多いんじゃないかと思います。
map
の問題は、ハッシュの代わりに配列の配列(多次元の配列)が返ってきてしまうという点。ここではHash#map
が使えます!
なので解決策の一つは、こうですね。
h = {bacon: 200, coconut: 300}
h.each { |k, v| h[k] = v*2 }
今回の例では、それぞれの値に2をかけています。
結果はこう。
{:bacon=>400, :coconut=>600}
でもRuby2.4以降なら、もっといい方法があります。
h.transform_values! { |v| v * 2 }
これはもともとRailsで使われていたメソッドで、今ではRailsのフレームワーク外でも使えるようになりました:)
Kernel#itself
(Ruby2.2)
もし、一見あまりパッとしたメソッドに見えないなと思ったとしたら、私も同意見です。
でもまあいくつか便利な例を見てみてください。
例えば単語の繰り返しを含む配列があり、その回数を数えたいとしましょう。
やり方は色々ありますが、このケースはKernel#itself
を試すのにぴったりです。
【例】
words = %w(cat cat tiger dog cat)
words.group_by(&:itself).transform_values(&:size)
Hash#transform_values!と組み合わせていることもお忘れなく!
もしtransform_values
が使えなければ、こう書くこともできます。
words
.group_by(&:itself)
.each_with_object({}) { |(k,v), hash| hash[k] = v.size }
Array#count
ただ数えたいだけのときってありますよね。
いつものcounter + loop
の代わりに、count
メソッドが使えます!
【例】
letters = %w(a a a b c d a)
letters.count("a")
# 4
配列の場合はブロックも引数に取ることができるので、もっと複雑なこともできます。
numbers = [1,2,3,4,5,6]
numbers.count(&:even?)
# 3
Enumerable#cycle
なんらかのパターンを繰り返したい?もしくはシンプルにon/offを切り替えたい?
なら、Enumerable#cycle
がぴったりです!
【例】
array = %w(a b c)
# Same as array * 3
array.cycle(3).to_a
私の場合は、「スイッチ」や「切り替え(toggle)」オブジェクトを生成する時に重宝しています。
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
.
もし既にご存知でしたら素晴らしい!もし知らなかったのであれば、便利だと思ってもらえれば幸いです🙂