DEV Community

Cover image for Today I learned about the splat operator in Ruby.
Patrick Wendo
Patrick Wendo

Posted on

Today I learned about the splat operator in Ruby.

Background

In my use case, I wanted to pass an array of fields into the .pluck operator for a query, but the pluck operator doesn't take in arrays. Obviously, the solution here is to destructure the array. Were it JS I probably would have just written .pluck(...pluck_fields) and moved on with my life. But funny enough, I have never had to destructure an array within function arguments. So I asked my supervisor and they told me to check the splat operator.

Splat Operator (* & **)

According to this article by Starr Horne, **They (splat operators) let you pass an array into a function expecting multiple arguments. The first item in the array becomes the first argument, the second item becomes the second argument and so on.*

Splat operator is more commonly used in function definition when the number of arguments is not known before hand, for instance:

def fun(*args)
    p args
end
Enter fullscreen mode Exit fullscreen mode

But in my use case, I want to focus on the first definition I mentioned, they can be used to pass an array into a function expecting multiple arguments. This directly solves my problem, where now i can pass an array of fields I want plucked to the pluck function,

.pluck(*pluck_fields)
Enter fullscreen mode Exit fullscreen mode

There is a lot more to explain about the splat operator and how it can also destructure Hashes as well, but that is beyond the scope of this post for now.

SPLAT!!!!

Discussion (5)

Collapse
swiknaba profile image
Lud
a = { foo: "bar" }

b = {
  bar: "baz",
  **a
}

puts b
> {
  bar: "baz",
  foo: "bar",
}
Enter fullscreen mode Exit fullscreen mode

;)

Collapse
jeremyf profile image
Jeremy Friesen

Welcome to the learning!

The * and ** are some of my favorite features; especially when you consider that if you have a hash with keys that are symbols you can prepend the ** and pass those as keyword args:

def my_method(hello:, gummy:)
  puts "Hello: #{hello}\nGummy: #{gummy}"
end

params = { hello: "world", gummy: "bears" }

my_method(**params)
Enter fullscreen mode Exit fullscreen mode

Which gets super cool when you have the case where params has more keys/values (e.g. params = { hello: "world", gummy: "bears", ninja: "turtle" })

You can then do the following:

more_params = { hello: "world", gummy: "bears", ninja: "turtle" }

my_method(**more_params.slice(:hello, :gummy))
Enter fullscreen mode Exit fullscreen mode

The above will only pass the :hello and :gummy values as named arguments.

The ** is a common pattern I use for dependency injection.

Collapse
w3ndo profile image
Patrick Wendo Author

This is definitely one of those operators you learn about and then suddenly realise how much easier it makes life.

Collapse
jeremyf profile image
Jeremy Friesen

Yes, and I'm excited to see where this learning takes you.

Collapse
michaeltharrington profile image
Michael Tharrington

Lol, love the cover image ya chose here!