Document 'it' and update numbered parameters docs (#12375)
This commit is contained in:
parent
477c505ac0
commit
173ae93e56
Notes:
git
2024-12-18 19:39:00 +00:00
Merged-By: zverok <zverok.offline@gmail.com>
87
proc.c
87
proc.c
@ -4252,19 +4252,86 @@ proc_ruby2_keywords(VALUE procval)
|
|||||||
* Since +return+ and +break+ exits the block itself in lambdas,
|
* Since +return+ and +break+ exits the block itself in lambdas,
|
||||||
* lambdas cannot be orphaned.
|
* lambdas cannot be orphaned.
|
||||||
*
|
*
|
||||||
* == Numbered parameters
|
* == Anonymous block parameters
|
||||||
*
|
*
|
||||||
* Numbered parameters are implicitly defined block parameters intended to
|
* To simplify writing short blocks, Ruby provides two different types of
|
||||||
* simplify writing short blocks:
|
* anonymous parameters: +it+ (single parameter) and numbered ones: <tt>_1</tt>,
|
||||||
|
* <tt>_2</tt> and so on.
|
||||||
*
|
*
|
||||||
* # Explicit parameter:
|
* # Explicit parameter:
|
||||||
* %w[test me please].each { |str| puts str.upcase } # prints TEST, ME, PLEASE
|
* %w[test me please].each { |str| puts str.upcase } # prints TEST, ME, PLEASE
|
||||||
* (1..5).map { |i| i**2 } # => [1, 4, 9, 16, 25]
|
* (1..5).map { |i| i**2 } # => [1, 4, 9, 16, 25]
|
||||||
*
|
*
|
||||||
* # Implicit parameter:
|
* # it:
|
||||||
|
* %w[test me please].each { puts it.upcase } # prints TEST, ME, PLEASE
|
||||||
|
* (1..5).map { it**2 } # => [1, 4, 9, 16, 25]
|
||||||
|
*
|
||||||
|
* # Numbered parameter:
|
||||||
* %w[test me please].each { puts _1.upcase } # prints TEST, ME, PLEASE
|
* %w[test me please].each { puts _1.upcase } # prints TEST, ME, PLEASE
|
||||||
* (1..5).map { _1**2 } # => [1, 4, 9, 16, 25]
|
* (1..5).map { _1**2 } # => [1, 4, 9, 16, 25]
|
||||||
*
|
*
|
||||||
|
* === +it+
|
||||||
|
*
|
||||||
|
* +it+ is a name that is available inside a block when no explicit parameters
|
||||||
|
* defined, as shown above.
|
||||||
|
*
|
||||||
|
* %w[test me please].each { puts it.upcase } # prints TEST, ME, PLEASE
|
||||||
|
* (1..5).map { it**2 } # => [1, 4, 9, 16, 25]
|
||||||
|
*
|
||||||
|
* +it+ is a "soft keyword": it is not a reserved name, and can be used as
|
||||||
|
* a name for methods and local variables:
|
||||||
|
*
|
||||||
|
* it = 5 # no warnings
|
||||||
|
* def it(&block) # RSpec-like API, no warnings
|
||||||
|
* # ...
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* +it+ can be used as a local variable even in blocks that use it as an
|
||||||
|
* implicit parameter (though this style is obviously confusing):
|
||||||
|
*
|
||||||
|
* [1, 2, 3].each {
|
||||||
|
* # takes a value of implicit parameter "it" and uses it to
|
||||||
|
* # define a local variable with the same name
|
||||||
|
* it = it**2
|
||||||
|
* p it
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* In a block with explicit parameters defined +it+ usage raises an exception:
|
||||||
|
*
|
||||||
|
* [1, 2, 3].each { |x| p it }
|
||||||
|
* # syntax error found (SyntaxError)
|
||||||
|
* # [1, 2, 3].each { |x| p it }
|
||||||
|
* # ^~ `it` is not allowed when an ordinary parameter is defined
|
||||||
|
*
|
||||||
|
* But if a local name (variable or method) is available, it would be used:
|
||||||
|
*
|
||||||
|
* it = 5
|
||||||
|
* [1, 2, 3].each { |x| p it }
|
||||||
|
* # Prints 5, 5, 5
|
||||||
|
*
|
||||||
|
* Blocks using +it+ can be nested:
|
||||||
|
*
|
||||||
|
* %w[test me].each { it.each_char { p it } }
|
||||||
|
* # Prints "t", "e", "s", "t", "m", "e"
|
||||||
|
*
|
||||||
|
* Blocks using +it+ are considered to have one parameter:
|
||||||
|
*
|
||||||
|
* p = proc { it**2 }
|
||||||
|
* l = lambda { it**2 }
|
||||||
|
* p.parameters # => [[:opt, nil]]
|
||||||
|
* p.arity # => 1
|
||||||
|
* l.parameters # => [[:req]]
|
||||||
|
* l.arity # => 1
|
||||||
|
*
|
||||||
|
* === Numbered parameters
|
||||||
|
*
|
||||||
|
* Numbered parameters are another way to name block parameters implicitly.
|
||||||
|
* Unlike +it+, numbered parameters allow to refer to several parameters
|
||||||
|
* in one block.
|
||||||
|
*
|
||||||
|
* %w[test me please].each { puts _1.upcase } # prints TEST, ME, PLEASE
|
||||||
|
* {a: 100, b: 200}.map { "#{_1} = #{_2}" } # => "a = 100", "b = 200"
|
||||||
|
*
|
||||||
* Parameter names from +_1+ to +_9+ are supported:
|
* Parameter names from +_1+ to +_9+ are supported:
|
||||||
*
|
*
|
||||||
* [10, 20, 30].zip([40, 50, 60], [70, 80, 90]).map { _1 + _2 + _3 }
|
* [10, 20, 30].zip([40, 50, 60], [70, 80, 90]).map { _1 + _2 + _3 }
|
||||||
@ -4279,11 +4346,16 @@ proc_ruby2_keywords(VALUE procval)
|
|||||||
* [10, 20, 30].map { |x| _1**2 }
|
* [10, 20, 30].map { |x| _1**2 }
|
||||||
* # SyntaxError (ordinary parameter is defined)
|
* # SyntaxError (ordinary parameter is defined)
|
||||||
*
|
*
|
||||||
|
* Numbered parameters can't be mixed with +it+ either:
|
||||||
|
*
|
||||||
|
* [10, 20, 30].map { _1 + it }
|
||||||
|
* # SyntaxError: `it` is not allowed when a numbered parameter is already used
|
||||||
|
*
|
||||||
* To avoid conflicts, naming local variables or method
|
* To avoid conflicts, naming local variables or method
|
||||||
* arguments +_1+, +_2+ and so on, causes a warning.
|
* arguments +_1+, +_2+ and so on, causes an error.
|
||||||
*
|
*
|
||||||
* _1 = 'test'
|
* _1 = 'test'
|
||||||
* # warning: `_1' is reserved as numbered parameter
|
* # ^~ _1 is reserved for numbered parameters (SyntaxError)
|
||||||
*
|
*
|
||||||
* Using implicit numbered parameters affects block's arity:
|
* Using implicit numbered parameters affects block's arity:
|
||||||
*
|
*
|
||||||
@ -4297,11 +4369,10 @@ proc_ruby2_keywords(VALUE procval)
|
|||||||
* Blocks with numbered parameters can't be nested:
|
* Blocks with numbered parameters can't be nested:
|
||||||
*
|
*
|
||||||
* %w[test me].each { _1.each_char { p _1 } }
|
* %w[test me].each { _1.each_char { p _1 } }
|
||||||
* # SyntaxError (numbered parameter is already used in outer block here)
|
* # numbered parameter is already used in outer block (SyntaxError)
|
||||||
* # %w[test me].each { _1.each_char { p _1 } }
|
* # %w[test me].each { _1.each_char { p _1 } }
|
||||||
* # ^~
|
* # ^~
|
||||||
*
|
*
|
||||||
* Numbered parameters were introduced in Ruby 2.7.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user