Reason #147 •
May 27th, 2026
Using blocks for iteration
The most common use case for blocks is iteration. Anyone who has used Ruby will have encountered blocks in this context, as they are used by methods like each, map, select and many others to perform operations on collections. Let's look at how we can implement a block-based iterator ourselves:
Ruby
require "net/http"
require "json"
class ApiPaginator
def initialize(resource_uri, per_page: 10)
@resource_uri = URI(resource_uri)
@per_page = per_page
end
def each
page = 1
loop do
response = Net::HTTP.get_response(@resource_uri + "?page=#{page}&limit=#{@per_page}")
resources = JSON.parse(response.body)
break if resources.empty?
resources.each { |resource| yield resource }
page += 1
end
end
end
paginator = ApiPaginator.new("https://6a174fac1b90031f81b237fe.mockapi.io/loving-ruby/posts")
paginator.each do |post|
puts post.fetch("title")
end
# Output:
# End of the Road
# Nature Boy
# ...
Now that we have each implemented, we can include Enumerable, and all our wildest dreams will come true:
Ruby
ApiPaginator.include(Enumerable)
paginator = ApiPaginator.new("https://6a174fac1b90031f81b237fe.mockapi.io/loving-ruby/posts")
titles = paginator.map { |post| post.fetch("title") }
# => ["End of the Road", "Nature Boy", ... ]
strawberry_fields = paginator.find do |post|
post.fetch("title").include?("Strawberry")
end
strawberry_fields.fetch("title")
# => "Strawberry Fields Forever"
Could this get any more straightforward? ❤️