Jozef Behr | 10 Ruby tricks to improve your code (or not)
Tags: ruby, tricks, improve, codenewbie
Published: 2023-01-18 07:52:54

Hello DEV's  Myself **Jozef Clifford Behr**, I want to show you 10 nice Ruby features that you may know or not. Anyway, it’s a quick read and it’s always interesting to learn new stuff, right?!

**1. Create a hash from a list of values**

You can create a hash from a list of values by using Hash[...]. It will create a hash like below:

```
Hash['key1', 'value1', 'key2', 'value2']

# => {"key1"=>"value1", "key2"=>"value2"}
```


**2. Lambda Literal ->**

Introduced quite recently and the new way recommended to define scopes in Rails, the -> sign, a.k.a Lambda Literal, allows you to create lambda easily.

```
a = -> { 1 + 1 }
a.call
# => 2

a = -> (v) { v + 1 }
a.call(2)
# => 3
```


**3. Double star (**)**

The double star is a neat little trick in Ruby. See the following method:

```
def my_method(a, *b, **c)
  return a, b, c
end
```

a is a regular parameter. *b will take all the parameters passed after the first one and put them in an array. **c will take any parameter given in the format key: value at the end of the method call.

See the following examples:

One parameter

```
my_method(1)
# => [1, [], {}]
```

More than one parameter

```
my_method(1, 2, 3, 4)
# => [1, [2, 3, 4], {}]
```

More than one parameter + hash-style parameters

```
my_method(1, 2, 3, 4, a: 1, b: 2)
# => [1, [2, 3, 4], {:a=>1, :b=>2}]
```


**4. Handle single object and array in the same way**

Sometimes you might want to give the option to either accept a single object or an array of objects. Instead of checking for the type of object you’ve received, you could use [*something] or Array(something).

Let’s assign two variables. The first one is a single digit and the second one is an array of digits.

```
stuff = 1
stuff_arr = [1, 2, 3]
```

In the following example, I use [*...] to loop through whatever is given.

```
[*stuff].each { |s| s }
[*stuff_arr].each { |s| s }
```

Same in this one but using Array(...).

```
Array(stuff).each { |s| s }
Array(stuff_arr).each { |s| s }
```


**5. Double Pipe Equals ||=**

The Double Pipe Equals is a great tool to write concise code.

It’s actually equivalent to the following:

```
a || a = b # Correct
```

And not this one, as a lot of people think:

```
a = a || b # Wrong
```

The second one doesn’t make sense because there is no point reassigning a if we already have it!

This operator can be used to create methods like this in your classes. I love to use it for calculations.

```
def total
  @total ||= (1..100000000).to_a.inject(:+)
end
```

Now you could have other method calling total to get the total value but it will only be calculated the first time.

**6. Mandatory hash parameters**

This one was introduced in Ruby 2.0. Instead of just defining a method that takes a hash in parameters like this:

```
def my_method({})
end
```

You can specify the keys that you are waiting for and even define default values for them! a and b are mandatory keys.

```
def my_method(a:, b:, c: 'default')
  return a, b, c
end
```

We can try to call it without giving a value for b but it won’t work.

```
my_method(a: 1)
# => ArgumentError: missing keyword: b
```

Since c has a default value, we can just call the method with a and b.

```
my_method(a: 1, b: 2)
# => [1, 2, "default"]

```
Or with all of them.

```
my_method(a: 1, b: 2, c: 3)
# => [1, 2, 3]
```

All we are doing is passing a hash and using some visual shortcuts but obviously, you can also pass a hash like this:

```
hash = { a: 1, b: 2, c: 3 }
my_method(hash)
# => [1, 2, 3]
```

**7. Generate array of alphabet or numbers**

You might want to generate a list of numbers or put the entire alphabet inside an array. Well, you can use ruby ranges to do this.

A to Z

```
('a'..'z').to_a
# => ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"]

```
1 to 10

```
(1..10).to_a
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
```

**8. Tap**

Tap is a nice little method that improves code readability. Let’s take the following class as an example.

```
class User
  attr_accessor :a, :b, :c
end
```

Now let’s say you want to instantiate a new user and assign a value to each of its attributes. You could do it like this:

```
def my_method
  o = User.new
  o.a = 1
  o.b = 2
  o.c = 3
  o
end
```

Or you could use tap to do it like this.

```
def my_method
  User.new.tap do |o|
    o.a = 1
    o.b = 2
    o.c = 3
  end
end
```

Basically, the tap method yields the calling object to the block and returns it.

**9. Default value for hash (Bad trick)**

By default, when trying to access a value not defined in a hash, you will receive nil. You can actually change this at initialization.

EDIT: Don’t do this unless you know what you’re doing. Checkout the comments below for a complete explanation.

In this first example, we define the default value to be 0 so when a[:a] is called, we’re getting 0 back and not nil.

```
a = Hash.new(0)
a[:a]
# => 0
```

We can pass anything to the Hash initializer. Let’s try with a hash!

```
a = Hash.new({})
a[:a]
# => {}
```

Or a weird string:

```
a = Hash.new('lolcat')
a[:a]
# => "lolcat"
```

**10. heredocs**

I personally dislike seeing heredocs that break the code flow and indentation. Since EOT takes into account the leading spaces, you usually have to stick the content to the left like this:

```
def my_method
  <<-EOT
Some
Very
Interesting
Stuff
  EOT
end
```

But there’s a trick to avoid that. By using the gsub method with a short regex, you can automatically remove the leading spaces which allows you to keep your indentation consistent.

```
def my_method
  <<-EOT.gsub(/^\s+/, '')
    Some
    Very
    Interesting
    Stuff
  EOT
end

```
I hope you enjoyed those little tricks and I’m sure you already knew some, if not all, of them. Let me know if you have other Ruby tricks that should be added to this list!