However, saying that the latter is "more readable" lacks foundation imo... both are conventions, both are simple to understand, and you can adapt to either quickly. I'd argue this is a case of "familiarity"/"readability" confusion.
A more practical argument is that "|u|" is more widely known by inexperienced ruby devs, and hence has an advantage on larger teams, especially those with turnover. With that said, I agree with author's position.
The only case where I've used a shorthand pattern like _1 is with regex matching where the matched groups are not named, so $1, $2, $3 refer to the first, second, third matched groups, etc. Having worked a lot with csvs (mentioned in an example), referencing the header (or creating one) has always been really valuable, using numbers is asking for trouble when the spec inevitably changes or when a dev wants to know if a script will work with some new file.
To take the exact example you gave, `users.map{ |u| do_something(u) }` is unambiguously better than `users.map{ |user| do_something(user) }`.
What we really want is `users.map{ do_something }`. It is only happenstance that ruby allows this form for methods only via `users.map(&:some_method)`, and we are stuck with forced variable names when calling other functions. Still, we can reduce the boilerplate as much as possible, and this is the basic argument of the article.
Also fine: `users.map{ |x| do_something(x) }` (the "x" as a conventional placeholder for the meaningless but syntactically necessary placeholder) and `users.map{ do_something(_1) }` (the _1 accomplishing the same thing). In either case, the "meaningful variable" is already there in the name "users" -- repeating it is mere stutter and detracts from, rather than enhancing, clarity.
The exception (as you noted) would be a longer multiline block where repeating `user` can aid short term memory, especially if the block contains other local variables.
Not sure what you are trying to say here, because there are so much odd about this that it is hard to penetrate.
First, & works on proc-able objects (those that are Procs or can be converted to them via #to_proc), not "methods", and what you show it being used with is a symbol, not a method. Symbol#to_proc on a symbol s produces a proc that is functionally something like:
->(*args, **kwargs) { args[0].send(s, args[1..-1, **kwargs] }
While that's complicated, the upshot is that it creates a proc that calls the method whose name is the symbol & was applied to on its first argument, passing its remaining arguments as the arguments to the method.> What we really want is `users.map{ do_something }`.
But if you want to pass a method on self, the only thing in Ruby that you can call like do_something(x), to map, you can do that without an expllcit block already, by using the Object#method method, which returns a Proc that is equivalent to calling the method:
users.map &method(:do_something)
And if you want to call a Proc object in a local variable called do_something to map (the closest thing to a "non-method function" that exists in Ruby), you can do that without an explicit block, even more concisely, because you don't have to convert it to a Proc first: users.map &do_somethingIn many languages (even in JS!) you can just map a function point-free, rather than having to introduce a variable just because syntax demands it, or worry about which syntax to use depending on if the "function" you're calling is a method on the object being mapped or something else. It's all noise.
> you can do that without an expllcit block already, by using the Object#method method, which returns a Proc that is equivalent to calling the method:
> users.map &method(:do_something)
Again, I am aware, and the ugliness of that solution proves the point I was trying to make -- it is even worse than the block syntax with a variable.
Yes, in many languages, "functions" are a thing that exists. In Ruby, there is no such thing as a function. The concept does not exist.
Which is why it is bizarre to talk about what you can and can't do with "functions" in Ruby, and to call kinds of different not-function things (including symbols, of all things) "functions" in that discussion. Its just applying language that makes no sense.
If variable names are well picked they provide guiding context hints that ease understanding. If you have only a terse pack of symbols, deciphering the code will be longer because you have to go trough more contextualization to understand where the code take place and what it actually operates over for which purpose.
This reminds me a lot of using(&:blabla). I'd prefer it: `billing_subscriptions.each { |bs| bs.status = ACTIVE}`
But don't mind me I'm just bikeshedding
We also don't allow single letter variable names. I'm an old school rubyist and find this to be an annoying constraint that can't be auto-corrected so it adds a little friction to writing code but arguing for more terse code is always a losing proposition so I just deal with it.
To be strictly serious we are talking about block parameters in ruby which contain the values yielded to it which, in an enumeration, is likely to be a value object from a collection and only occasionally an index (where you've explicitly chained `#with_index` for e.g.). If you are nesting deep enough in ruby to call for `k` then, yes, it would be bad practice.
With only one variable, and sometimes with very simple expressions with more than one, you probably get a readability benefit by avoiding stuttering:
{ _1 + _2 }
reads a little better than: { |x, y| x + y }
But with any even slightly complex expression in the block, that goes from a benefit to a cost.