知っておくと便利!より良いコードを書くための7つのRubyメソッド
適切なRubyメソッドを使いこなせば、作業を大幅に節約できることをご存じでしたか?
知っているメソッドが多ければ多いほど、動作するコードをより速く書けるようになり、パフォーマンスと品質の両面でコードの質も向上します。
そこで今回は、あまり知られていない7つの便利なメソッドをご紹介します。
目次
- 1. Integer#digits(Ruby 2.4)
- 2. tapメソッド
- 3. Array#values_at
- 4. Hash#transform_values(Ruby 2.4)
- 5. Kernel#itself(Ruby 2.2)
- 6. Array#count
- 7. Enumerable#cycle
- 8. まとめ
1. Integer#digitsメソッド(Ruby 2.4)
Ruby 2.4で導入された新しいメソッドで、整数の各桁を個別に扱いたい場合に非常に便利です。
補足: Ruby 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]
ずっとシンプルになりましたね!
2. tapメソッド
オブジェクトを作成し、いくつかのメソッドを呼び出して、その同じオブジェクトを返したいことがあります。
通常は次のように書く必要があります:
user = User.new user.name = "John" user
問題は、この一時変数を扱わなければならないことです。
ここでtapメソッドの出番です!
tapを使うと、先ほどの例は次のようになります:
User.new.tap { |user| user.name = "John" }
一時変数が消えて、コードがすっきりしました。これは良いことですね 🙂
3. 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]
4. 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}
Ruby 2.4以降では、もっと良い方法があります:
h.transform_values! { |v| v * 2 }
これはRails由来のメソッドの一つで、現在ではフレームワーク外でも使えるようになっています 🙂
5. Kernel#itself(Ruby 2.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 }
補足: itselfメソッドはドキュメント上ではObjectクラスの下に表示されますが、実際にはKernelモジュールで定義されています。
6. Array#count
単純に何かを数えたいだけのこともあります。
典型的なカウンター+ループの代わりに、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
7. Enumerable#cycle
パターンを繰り返したい?あるいは簡単なオン/オフのトグルが必要?
そんなときはEnumerable#cycleがぴったりかもしれません!
例:
array = %w(a b c) # array * 3 と同じ array.cycle(3).to_a
個人的にお気に入りのcycleの使い方は、「スイッチ」や「トグル」オブジェクトを作ることです。
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という便利なメソッドを学びました。
すでにご存じの方もいたでしょうが、初めて知った方はぜひ活用してみてください 🙂
この記事が気に入ったら、友人にもシェアして楽しんでもらいましょう!
-
Rubyのメソッド入門:defキーワードで独自のメソッドを定義する方法
Rubyにおける「メソッド」とは、特定の目的のためにひとまとめにされた、1行以上のRubyコードのことです。 このコードのまとまりには名前が付けられており、一度定義してしまえば、同じコードを何度も書いたりコピー&ペーストしたりすることなく、必要なときにいつでも再利用できます。 メソッドの主な役割 メソッドの目的は、大きく分けて以下のようなものがあります。 情報を取得する オブジェクトを変更・生成する データをフィルタリング・整形する 具体例 例1: Arrayオブジェクトに対するsizeメソッドは、配列内の要素数を返します(情報の取得)。 例2: popメソッドは、配列から最後の要素を取り
-
Rubyでの静的分析入門!parser gemでメソッド定義を抽出する方法
ソースコードを解析して、すべてのメソッドがどこで定義され、どんな引数を受け取るのかを把握したいと思ったことはありませんか? どうすれば実現できるのでしょうか? 最初に思いつくのは、正規表現(regexp)を書くことかもしれません。 しかし、もっと良い方法があるとしたらどうでしょう? 答えは「あります」! 静的解析(Static Analysis)とは、ソースコードそのものから情報を抽出するためのテクニックです。 これは、ソースコードをトークンへと変換する(パースする)ことで実現されます。 それでは早速見ていきましょう! parser gemを使う Rubyには標準ライブラリとしてRipper