@@ -4252,19 +4252,86 @@ proc_ruby2_keywords(VALUE procval)
42524252 * Since +return+ and +break+ exits the block itself in lambdas,
42534253 * lambdas cannot be orphaned.
42544254 *
4255- * == Numbered parameters
4255+ * == Anonymous block parameters
42564256 *
4257- * Numbered parameters are implicitly defined block parameters intended to
4258- * simplify writing short blocks:
4257+ * To simplify writing short blocks, Ruby provides two different types of
4258+ * anonymous parameters: +it+ (single parameter) and numbered ones: <tt>_1</tt>,
4259+ * <tt>_2</tt> and so on.
42594260 *
42604261 * # Explicit parameter:
42614262 * %w[test me please].each { |str| puts str.upcase } # prints TEST, ME, PLEASE
42624263 * (1..5).map { |i| i**2 } # => [1, 4, 9, 16, 25]
42634264 *
4264- * # Implicit parameter:
4265+ * # it:
4266+ * %w[test me please].each { puts it.upcase } # prints TEST, ME, PLEASE
4267+ * (1..5).map { it**2 } # => [1, 4, 9, 16, 25]
4268+ *
4269+ * # Numbered parameter:
42654270 * %w[test me please].each { puts _1.upcase } # prints TEST, ME, PLEASE
42664271 * (1..5).map { _1**2 } # => [1, 4, 9, 16, 25]
42674272 *
4273+ * === +it+
4274+ *
4275+ * +it+ is a name that is available inside a block when no explicit parameters
4276+ * defined, as shown above.
4277+ *
4278+ * %w[test me please].each { puts it.upcase } # prints TEST, ME, PLEASE
4279+ * (1..5).map { it**2 } # => [1, 4, 9, 16, 25]
4280+ *
4281+ * +it+ is a "soft keyword": it is not a reserved name, and can be used as
4282+ * a name for methods and local variables:
4283+ *
4284+ * it = 5 # no warnings
4285+ * def it(&block) # RSpec-like API, no warnings
4286+ * # ...
4287+ * end
4288+ *
4289+ * +it+ can be used as a local variable even in blocks that use it as an
4290+ * implicit parameter (though this style is obviously confusing):
4291+ *
4292+ * [1, 2, 3].each {
4293+ * # takes a value of implicit parameter "it" and uses it to
4294+ * # define a local variable with the same name
4295+ * it = it**2
4296+ * p it
4297+ * }
4298+ *
4299+ * In a block with explicit parameters defined +it+ usage raises an exception:
4300+ *
4301+ * [1, 2, 3].each { |x| p it }
4302+ * # syntax error found (SyntaxError)
4303+ * # [1, 2, 3].each { |x| p it }
4304+ * # ^~ `it` is not allowed when an ordinary parameter is defined
4305+ *
4306+ * But if a local name (variable or method) is available, it would be used:
4307+ *
4308+ * it = 5
4309+ * [1, 2, 3].each { |x| p it }
4310+ * # Prints 5, 5, 5
4311+ *
4312+ * Blocks using +it+ can be nested:
4313+ *
4314+ * %w[test me].each { it.each_char { p it } }
4315+ * # Prints "t", "e", "s", "t", "m", "e"
4316+ *
4317+ * Blocks using +it+ are considered to have one parameter:
4318+ *
4319+ * p = proc { it**2 }
4320+ * l = lambda { it**2 }
4321+ * p.parameters # => [[:opt, nil]]
4322+ * p.arity # => 1
4323+ * l.parameters # => [[:req]]
4324+ * l.arity # => 1
4325+ *
4326+ * === Numbered parameters
4327+ *
4328+ * Numbered parameters are another way to name block parameters implicitly.
4329+ * Unlike +it+, numbered parameters allow to refer to several parameters
4330+ * in one block.
4331+ *
4332+ * %w[test me please].each { puts _1.upcase } # prints TEST, ME, PLEASE
4333+ * {a: 100, b: 200}.map { "#{_1} = #{_2}" } # => "a = 100", "b = 200"
4334+ *
42684335 * Parameter names from +_1+ to +_9+ are supported:
42694336 *
42704337 * [10, 20, 30].zip([40, 50, 60], [70, 80, 90]).map { _1 + _2 + _3 }
@@ -4279,11 +4346,16 @@ proc_ruby2_keywords(VALUE procval)
42794346 * [10, 20, 30].map { |x| _1**2 }
42804347 * # SyntaxError (ordinary parameter is defined)
42814348 *
4349+ * Numbered parameters can't be mixed with +it+ either:
4350+ *
4351+ * [10, 20, 30].map { _1 + it }
4352+ * # SyntaxError: `it` is not allowed when a numbered parameter is already used
4353+ *
42824354 * To avoid conflicts, naming local variables or method
4283- * arguments +_1+, +_2+ and so on, causes a warning .
4355+ * arguments +_1+, +_2+ and so on, causes an error .
42844356 *
4285- * _1 = 'test'
4286- * # warning: `_1' is reserved as numbered parameter
4357+ * _1 = 'test'
4358+ * # ^~ _1 is reserved for numbered parameters (SyntaxError)
42874359 *
42884360 * Using implicit numbered parameters affects block's arity:
42894361 *
@@ -4297,11 +4369,10 @@ proc_ruby2_keywords(VALUE procval)
42974369 * Blocks with numbered parameters can't be nested:
42984370 *
42994371 * %w[test me].each { _1.each_char { p _1 } }
4300- * # SyntaxError ( numbered parameter is already used in outer block here )
4372+ * # numbered parameter is already used in outer block (SyntaxError )
43014373 * # %w[test me].each { _1.each_char { p _1 } }
43024374 * # ^~
43034375 *
4304- * Numbered parameters were introduced in Ruby 2.7.
43054376 */
43064377
43074378
0 commit comments