The maze book for programmers!
PragProg Amazon

Algorithms, circle mazes, hex grids, masking, weaving, braiding, 3D and 4D grids, spheres, and more!

DRM-Free Ebook

The Buckblog

assorted ramblings by Jamis Buck

Little Things: Introspecting Block Parameters

12 December 2015 — The author uses Ruby's `Proc#parameters` feature to implement a simple way to access data in a Hash — 1-minute read

This week I stumbled across a rather esoteric feature of Ruby, but one that actually proved really, really useful with something I’m doing for a client of mine. The feature? Proc#parameters. From the Ruby docs:

prc = lambda{|x, y=42, *other|}
prc.parameters  #=> [[:req, :x], [:opt, :y], [:rest, :other]]

Since I don’t yet have permission from my client to share the actual code I wrote, I’ll demonstrate this esoteric little feature by monkeypatching Hash and adding a using method. The end result will let us access Hash keys that match the names of the parameters we pass to the block, like this:

hash = {
  first_name: "John",
  last_name:  "Smith",
  age: 35,
  # ...

hash.using do |first_name, last_name|
  puts "Hello, #{first_name} #{last_name}."

# or even...

circle = {
  radius: 5,
  color: "blue",
  # ...

area = circle.using { |radius| Math::PI * radius**2 }

(Admittedly, these examples are a bit contrived, but I’m really quite in love with this idea. Hopefully I get to share the real use case eventually!)

The implementation of #using is delightfully simple:

class Hash
  module Using
    def using(&block)
      values = do |(type, name)|

  include Using

That’s it! We just inspect the parameters of the block, map the parameter names to the corresponding values, and invoke the block with those values as arguments.

I love Ruby. Fifteen years, and going strong.