ruby / rbs

Type Signature for Ruby
Other
1.94k stars 211 forks source link

Add `Enumerator::_Each` interface #1915

Closed ParadoxV5 closed 2 months ago

ParadoxV5 commented 3 months ago

It is a common pattern for #each to support both yielding to a block and returning an Enumerator when no block given. I add this interface as a convenience for library classes; it is not a replacement for ::_Each, which does not require no-block support.

soutaro just for clarity, I'm not arguing for a revision of the existing one, but to add a new one. The reasoning is, the current _Each already describes the requirement for implementing a class decorated with Enumerable. But an _EnumEach is common enough (IMO) to warrant defining it as a common interface (as most core and stdlib enumerables already do it). ⸺ https://github.com/ruby/rbs/issues/424#issuecomment-712034447

I put this interface under the Enumerator namespace to represent how it’s a “special” edition. Regarding why I’m sticking with _Each:

I think _MethodName should be restricted to interfaces that implement that method_name minimally. […] If you want to specify that your class implements each "correctly", then yes, you should have these two interfaces and a shorthand might be useful. ⸺ https://github.com/ruby/rbs/issues/424#issuecomment-711449179

sampersand commented 2 months ago

I approve! Not only do I agree, I think we should think about changing Enumerable to have it as a prerequisite.

ParadoxV5 commented 2 months ago

I think we should think about changing Enumerable to have it as a prerequisite.

Enumerable technically does not require the #each to have a no-block branch at all. Although it would be an easy oversight to assume the no-block branch exists from any ordinary Enumerable (I may have fallen into this trap before).