This blog is part of our Ruby 2.7 series. Ruby 2.7.0 was released on Dec 25, 2019.

At some point, all of us have used names like a , n , i etc for block parameters. Below are few examples where numbered parameters can come in handy.

> ( 1 .. 10 ). each { | n | p n * 3 } > { a: [ 1 , 2 , 3 ], b: [ 2 , 4 , 6 ], c: [ 3 , 6 , 9 ] }. each { | _k , v | p v } > [ 10 , 100 , 1000 ]. each_with_index { | n , i | p n , i }

Ruby 2.7 introduces a new way to access block parameters. Ruby 2.7 onwards, if block parameters are obvious and we wish to not use absurd names like n or i etc, we can use numbered parameters which are available inside a block by default.

We can use _1 for first parameter, _2 for second parameter and so on.

Here’s how Ruby 2.7 provides numbered parameters inside a block. Below shown are the examples from above, only this time using numbered parameters.

> ( 1 .. 10 ). each { p _1 * 3 } > { a: [ 1 , 2 , 3 ], b: [ 2 , 4 , 6 ], c: [ 3 , 6 , 9 ] }. each { p _2 } > [ 10 , 100 , 1000 ]. each_with_index { p _1 , _2 }

Like mentioned in News-2.7.0 docs, Ruby now raises a warning if we try to define local variable in the format _1 . Local variable will have precedence over numbered parameter inside the block.

> _1 = 0 > => warning: `_1' is reserved for numbered parameter; consider another name > [10].each { p _1 } > => 0

Numbered parameters are not accessible inside the block if we define ordinary parameters. If we try to access _1 when ordinary parameters are defined, then ruby raises SyntaxError like shown below.

> [ "a" , "b" , "c" ]. each_with_index { | alphabet , index | p _1 , _2 } => SyntaxError (( irb ): 1 : ordinary parameter is defined )

This feature was suggested 9 years back and came back in discussion last year. After many suggestions community agreed to use _1 syntax.

Head to following links to read the discussion behind numbered parameters, Feature #4475 and Discussion #15723.

Here’s relevant commit for this feature.