Issue #19370 has been updated by zverok (Victor Shepelev).
To be completely honest, I think I have some counterarguments to the current conclusions.
I believe the code that looks "logically possible" should be "physically
possible" (unless there is a good argument why it is impossible, like the ambiguity
of parsing).
In the case of allowing forwarding in blocks, I find two questions below (with their
answers) to be important.
**Would this create new types of confusion?**
I believe it **would not**.
* `def m(*); ->(*) { p(*) };`, if it would **forward the proc args** MIGHT BE
considered confusing. But it is confusing in EXACTLY the same way as `def m(a); ->(a) {
p(a) };`; no new complication to explain here. Such cases with named variables are easily
caught by the linter if the user wants (and doesn't stand in the way of quick
experimenting).
* but both current behavior (treating it as forwarding method's args) and proposed
behaviors (prohibit some of the cases for the sake of disallowing potentially confusing
code) would create **new types of confusion**. Procs/lambdas are Ruby's main
functional construct, and the main intuition is that you can do with them what you can do
with methods. Breaking this intuition creates learning impediments and falls into a mental
bag of "weird language quirks you just need to remember."
**Are there types of code where forwarding in procs/lambdas is necessary?**
I believe **there are**. [One of the important
drivers](https://bugs.ruby-lang.org/issues/16378) of `...` design was considering
`method_missing`/`send`, i.e., metaprogramming.
One of the main types of metaprogramming is `define_method`, which the author frequently
wants to be short and expressive and allow to do everything that regular `def` does.
The "start with `method_missing`, and then switch to `define_method` when the code
matures" is one of the widespread approaches to designing various DSLs, and at that
moment, the author is in a weird situation:
```ruby
# code I had
def method_missing(name, **)
if ALLOWED_OPERATIONS.key?(name)
ALLOWED_OPERATIONS[name].call(**)
else
super
end
end
# code I want to replace it with:
ALLOWED_OPERATIONS.each do |name, op|
define_method(name) { |**| op.call(**) }
end
```
...but for some reason, I can not.
I think it feels like a bug and nothing else. And for relatively new syntax features
(which meet some pushback from the community anyway), such artificial limitations might
lower the adoption: "Well, I tried it once, it never worked the way I wanted it to.
Don't remember the exact reason, but it was confusing, so I don't use it anymore
and recommend everyone to do the same."
(Very infrequently such cases would be posted to the bug tracker/discussed in public for
the core team to notice that there _was_ such need.)
----------------------------------------
Feature #19370: Anonymous parameters for blocks?
https://bugs.ruby-lang.org/issues/19370#change-105409
* Author: zverok (Victor Shepelev)
* Status: Assigned
* Priority: Normal
* Assignee: matz (Yukihiro Matsumoto)
----------------------------------------
Just to clarify: are anonymous parameters delegation is planned to support in blocks?
It would be a nice addition, if it is possible to implement:
```ruby
# data in form [request method, URL, params]:
[
[:get, 'https://google.com', {q: 'Ruby'}, {'User-Argent':
'Google-Chrome'}],
[:post, 'https://gist.github.com', 'body'],
# ...
].each { |method, *| request(method.to_s.upcase, *) }
```
...and at the very least, consistent with what the method definition can have.
If they are NOT planned to be implemented, I believe that at least error messages should
be made much clearer, because currently, this would happen while running the code above:
no anonymous rest parameter (SyntaxError)
I understand the reason (the `request` clause doesn't "see" anonymous
parameter of the **block**, and claims that current **method** doesn't have them), but
it looks honestly confusing and inconsistent.
--
https://bugs.ruby-lang.org/