7 Little-Known Ruby Methods To Help You Write Better Code

Did you know that using the right Ruby method can save you a lot of work?

The more methods you are familiar with the faster you can produce working code & the better this code will be, both in performance & quality.

That’s why today I want to introduce 7 interesting methods to you that you may not have seen before.

Contents

Integer#digits Method (Ruby 2.4)

This is a new method introduced in Ruby 2.4 & it’s very useful if you want to work with the individual digits of an Integer.

Note: In case you are not up to speed on Ruby 2.4 changes, Fixnum & Bignum are now deprecated & both merged into Integer.

You may think that using array-like indexing may work:

2[0]

# 0

2[1]

# 1

But what you get are not the digits, but the binary bits that make up this number.

So pre-digits method the typical solution was to convert the number into a string, then break that string into an array of characters using the chars method, and finally convert every string back into an integer.

Example:

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

[3, 2, 1]

But in a post-digits method world, you can simply do this:

123.digits

[3, 2, 1]

Much better, isn’t it?

Video:

[responsive_video type=’youtube’ hide_related=’0′ hide_logo=’0′ hide_controls=’0′ hide_title=’0′ hide_fullscreen=’0′ autoplay=’0′]https://www.youtube.com/watch?v=LFKNhpiOXUU[/responsive_video]

The Tap Method

Sometimes you want to create an object, call some methods on it & return that same object.

You would have to do something like this:

user = User.new

user.name = "John"

user

The problem is that we have to deal with this temporary variable.

Here’s where the tap method comes to the rescue!

With tap the last example becomes this:

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

Notice how the temporary variable is gone, which is a good thing 🙂

Array#values_at

If you want to get multiple non-sequential values from an array or a hash you could do this:

arr = [1,2,3,4,5]

a, b, c = arr[0], arr[1], arr[4]

Or you could use the values_at method:

arr = [1,2,3,4,5]

a, b, c = arr.values_at(0, 1, 4)

This also works with a hash:

hash = {bacon: 300, chocolate: 200}

p hash.values_at(:bacon, :chocolate)

# [300, 200]

Hash#transform_values (Ruby 2.4)

Let’s say you have a hash & want to change all the values for some reason.

Sort of what you would do with Array#map.

The problem with map is that you will get an array-of-arrays (multi-dimensional array) instead of a hash. Also there is no Hash#map!.

So one solution could be this:

h = {bacon: 200, coconut: 300}

h.each { |k,v| h[k] = v*2 }

In this example we multiply each value times two.

Which results in:

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

Since Ruby 2.4 there is a better way to do this:

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

This is another of those methods coming from Rails, which is now available outside the framework 🙂

Kernel#itself (Ruby 2.2)

If you told me that this method does not look very interesting at first I would agree with you.

But the reason is that you need to see some good examples.

So let’s say we have an array with repeated words & we want to count them…

While there are many ways to do this, I think this is a great case for testing out our new friend: Kernel#itself.

Example:

words = %w(cat cat tiger dog cat)

words.group_by(&:itself).transform_values(&:size)

Notice how I also combined this with Hash#transform_values!

If transform_values is not available you can do this:

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

Video:

[responsive_video type=’youtube’ hide_related=’0′ hide_logo=’0′ hide_controls=’0′ hide_title=’0′ hide_fullscreen=’0′ autoplay=’0′]https://www.youtube.com/watch?v=2zevygUebeo[/responsive_video]

Note: The itself method shows up under the Object class in the documentation, but the method is defined on the Kernel module.

Array#count

Sometimes you just need to count something.

Instead of using the typical counter + loop you can use the count method!

Example:

letters = %w(a a a b c d a)

letters.count("a")

# 4

The array version of this method also takes a block, so you can do more complex counting.

numbers = [1,2,3,4,5,6]

numbers.count(&:even?)

# 3

Video:

[responsive_video type=’youtube’ hide_related=’0′ hide_logo=’0′ hide_controls=’0′ hide_title=’0′ hide_fullscreen=’0′ autoplay=’0′]https://www.youtube.com/watch?v=x7kApCyizlo[/responsive_video]

Enumerable#cycle

Do you want to repeat some pattern? Or maybe you need an easy on/off toggle?

Then Enumerable#cycle might be what you are looking for!

Example:

array = %w(a b c)

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

But my favorite use for cycle is to create a “switch” or “toggle” object.

switch = %w(on off).cycle

switch.next

The nice thing about this is that you don’t need to check the current value of the switch to update it manually.

You can just call next & Ruby will know exactly what to do 🙂

[responsive_video type=’youtube’ hide_related=’0′ hide_logo=’0′ hide_controls=’0′ hide_title=’0′ hide_fullscreen=’0′ autoplay=’0′]https://www.youtube.com/watch?v=jFmveSKn5mA[/responsive_video]

Summary

You have learned about some new useful methods: Integer#digits, Kernel#tap, Array#values_at, Hash#transform_values, Kernel#itself, Array#count, Enumerable#cycle.

If you already knew about these great! If not I hope you find them useful 🙂

Enjoyed this article? Then share it with your friends so they can enjoy it too!

14 thoughts on “7 Little-Known Ruby Methods To Help You Write Better Code”

  1. That was pretty helpful. I knew couple of methods and have used ’em in the past, but some of ’em really looks interesting. Cant wait to play with ’em. Thank you Jesus!

  2. Hey mate,

    For what it’s worth, ActiveRecord gives you tap-like functionality out of the box, so where you’ve done:

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

    The following also works:

    User.new { |user| user.name = "John" }

  3. You usually want the digits in the same order, so it should be `123.to_s.chars.map(&:to_i)` vs. `123.digits.reverse`.

    • The neat thing about the way the digits are arranged is that their array indexes correlated with the power of ten they represent. Or in code:

      [3,2,1].each_with_index.reduce(0) { |sum, (n, i)| sum + n * 10 ** i }
      #=> 123
      

Comments are closed.