Skip to content

Anonymous block forwarding #12110

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
straight-shoota opened this issue Jun 10, 2022 · 2 comments
Open

Anonymous block forwarding #12110

straight-shoota opened this issue Jun 10, 2022 · 2 comments

Comments

@straight-shoota
Copy link
Member

Ruby 3.1 introduced anonymous block forwarding. An anonymous block argument can be forwarded to another method call using & as block argument. This is effectively just syntax sugar for forwarding the block explicitly via a block that yields. So it's a bit more concise.

def bar(&)
  foo(&)
end

equivalent to:

def bar(&)
  foo { |*args| yield *args }
end

This feature would not be a huge thing, but a nice little convenience feature.

@HertzDevil
Copy link
Contributor

HertzDevil commented Jan 13, 2023

Ruby 3.2 adds anonymous single and double splats on top of &:

def foo(*args, **opts)
  [args, opts]
end

def bar(*, **)
  foo(*, **)
end

bar(1, 2, x: 3, y: 4) # => [[1, 2], {:x=>3, :y=>4}]

They also work inside array and hash literals:

def foo(*)
  [1, *, 5]
end

foo(2, 3, 4) # => [1, 2, 3, 4, 5]

def bar(**)
  {a: 1, **, d: 4}
end

bar(b: 2, c: 3) # => {:a=>1, :b=>2, :c=>3, :d=>4}

At this point it is probably too late for us since a bare single splat in Crystal already indicates a lack of extra positional parameters.

@straight-shoota
Copy link
Member Author

At this point it is probably too late for us since a bare single splat in Crystal already indicates a lack of extra positional parameters.

I guess technically it would be unambiguous. If * us used as any anonymous forward anywhere in the body, it's a catch-all, otherwise not.
But that would be confusing when you can't tell from the signature. That's the same problem we currently have with blocks and yield, #8764).

Plus, it's simply unnecessary. You can just give it a name and use that. Requires no special syntax.

That's different with & of course because you can't give it a name and simply forward it that way. That would capture the block, turning it into a proc which won't work with yield then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants