Anonymous Block Forwarding in Ruby
In this post, we'll take a look at the anonymous block forwarding feature added in Ruby 3.1. It lets you replace your execute(&block) calls with execute(&). Not only it saves you from coming up with a variable (most likely blk), it also looks pretty sweet. I dig it.
You probably have used (or at least heard about) the argument forwarding feature in Ruby, which was added in Ruby 2.7, that lets you forward all the arguments passed to a method, as they are, to another method, using the three dots ... syntax.
This includes all positional, named, and even block arguments.
def execute(action="", **options)
p action # get
p options # {:url=>"/test", :values=>[201, 202]}
yield "fake response"
end
def perform(...)
# execute receives all the arguments
# received by the perform function
execute(...)
end
perform action="get", url: "/test", values: [201, 202] do |result|
p result # "fake response"
end
Did you know that there's a similar shorthand to forward a block anonymously? I learned this very recently (yesterday!), and I love it.
Notice the perform method in the following example:
def execute(&blk)
yield "response 1"
blk.call "response 2"
end
def perform(&)
# execute receives the same block
# received by the perform function
execute(&)
end
perform do |result|
p result
end
# Output:
# "response 1"
# "response 2"
Earlier, you'd have done something like:
def perform(&blk)
execute(&blk)
end
But starting in Ruby 3.1, you can do this:
def perform(&)
execute(&)
end
Pretty cool, right? Also looks pretty nice, in my opinion. What do you think?
If you like this syntax, and would like to enforce it via Rubocop (Rails 8 ships with a default Rubocop linter out of box), you can use the following Rule:
Naming/BlockForwarding:
EnforcedStyle: anonymous
On the other hand, if you prefer the older explicit version, enforce it with this rule:
Naming/BlockForwarding:
EnforcedStyle: explicit
P.S. For an in-depth explanation, I suggest reading this post from zverok. It goes into much more depth.
Sign up for my newsletter
Let's learn to become better developers.
Comments (2)
Pretty nice! Thanks for the article (again)
Very cool.