Revisiting it once again, I still propose to treat &.
in two ways:
- As the first block argument (like it is now):
["a", "b"].map &.upcase
# Expands to
["a", "b"].map { |x| x.upcase }
def foo(&block : String, String ->)
yield "foo", "bar"
end
puts foo &.upcase # FOO
- As the first block argument (proposed): it’s not a typo
["a", "b"].map { &.upcase }
# Expands to
["a", "b"].map { |x| x.upcase }
def foo(&block : String, String ->)
yield "foo", "bar"
end
puts foo { &.upcase } # FOO
I honestly do not understand why you don’t approve it.
Some considerations:
Q: What if is there are multiple block arguments?
A: &.
should be the first argument shortcut, others are omitted. If you want multiple args, specify them explicitly. &.
would still work in this case:
["a", "b"].map_with_index { &.upcase } # OK
["a", "b"].map_with_index { |s, i| &.upcase * i } # OK
Q: What about nested blocks?
A: In case of nesting, the deeper block takes precedence:
"foo".tap do
["a", "b"].map_with_index { &.upcase } # Expands to `s.upcase`
end
"foo".tap do
["a", "b"].map_with_index { |s, i| &.upcase } # Still expands to `s.upcase`
end
Q: What is your use-case?
A: Onyx::SQL join query yields a nested query. Instead of this:
posts = Onyx.query(Post
.join(:author) do |x|
x.join(:settings) do |y|
y.select(:foo)
y.where(active: true)
end
end
)
I could write this:
posts = Onyx.query(Post
.join(:author) do
&.join(:settings) do
&.select(:foo)
&.where(active: true)
end
end
)
I’d love to hear @bcardiff’s opinion on this proposal.
P.S: &n
syntax is ugly.