-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Make Array#transpose
, Enumerable#reject
, Enumerable#to_h
work with tuples
#10445
Make Array#transpose
, Enumerable#reject
, Enumerable#to_h
work with tuples
#10445
Conversation
I wonder if, instead of adding a nodoc methods to every type here, we can introduce an internal type inside Enumerable, with a method that computes this. For every object except tuple it calls first, but for tuple it would be different. What do you think? |
#10429 does that: module Enumerable(T)
def self.element_type(x)
x.each { |elem| return elem }
::raise ""
end
end
class Foo # not an Enumerable
def each
yield 1
yield 'a'
end
end
typeof(Enumerable.element_type([1, 'a'])) # => (Char | Int32)
typeof(Enumerable.element_type({1, 'a'})) # => (Char | Int32)
typeof(Enumerable.element_type(Foo.new)) # => (Char | Int32) Like |
Cool! Can we bring that method from that PR into this one? I'll try to review the other one this week. Sorry, we can't catch up with so many great PRs! 😅 |
I didn't replace the internal methods in |
src/enumerable.cr
Outdated
# NOTE: there should never be a need to call this method outside the standard library. | ||
def self.element_type(x) | ||
x.each { |elem| return elem } | ||
::raise "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is intended for being used in typeof
and not supposed to be actually called. But still, it can be. And then it should raise a proper exception, instead of an empty message.
Unfortunately it's not possible to move the typeof
into the method because of nesting calls and yielded values. That would probably be the best solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want element_type
as a public method like this?
I realize it's already merged from #10429, thus not necessarily subject to this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It cannot be even protected because splat expansions must be able to access the method in any scope, for the same reason as ::String.interpolation
being public.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's actually good to have this public because it enables shards to use it if they need it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But what about the empty raise? It's public API and can be called outside of typeof
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either EmptyError
or a generic BUG:
exception, I guess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: #10429 is merged, and now the diff from src/enumerable.cr entirely disappears, as it exactly matches what's in master.
Array#transpose
, Enumerable#reject
, Enumerable#to_h
work with tuples
As noted in #3718 (comment), methods cannot depend on
typeof(exp.first)
ifexp
is anEnumerable
orIndexable
, because it breaks whenexp
is also aTuple
:This PR fixes them:
Some methods like
Enumerable#flat_map
calltypeof(yield first)
, which is okay as long as the method also yields each element from the collection itself, but for clarity thesefirst
calls insidetypeof
s are also replaced withfirst_internal
Enumerable.element_type(self)
.