Skip to content
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

Impossible to iterate over types in a Tuple #4737

Closed
oprypin opened this issue Jul 22, 2017 · 4 comments
Closed

Impossible to iterate over types in a Tuple #4737

oprypin opened this issue Jul 22, 2017 · 4 comments
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib
Milestone

Comments

@oprypin
Copy link
Member

oprypin commented Jul 22, 2017

It is clear that the original intent of Tuple#types was to return a proper tuple of types that can be usefully iterated over at runtime.
However its behavior indirectly changed somewhere along the way without checking whether it is still useful (specs were updated instead, and the nuance in documentation was lost as well). Now tuple.types is literally the same as typeof(tuple), and I don't see any reason for it to exist in this state.

Strangely enough, within the codebase there is a Tuple.types method that behaves exactly as everyone would expect, but it's hidden in specs.

What I want: iterate over a Tuple's types at runtime, like so:

def create_random_tuple
  {"a" == "a" ? 5 : 5u8, "string"}
end

struct Tuple
  def self.types
    {% begin %}
    {
      {% for type in T %}
        {{type}},
      {% end %}
    }
  {% end %}
  end
end

a = create_random_tuple
typeof(a).types.each do |t|
  p t
  # (Int32 | UInt8)
  # String
end

but without adding my own extension to Tuple, and without this workaround that @Groogy showed.

At the moment this seems impossible:

def create_random_tuple
  {"a" == "a" ? 5 : 5u8, "string"}
end

a = create_random_tuple
a.types.each do |t|
  p t
end
# Error in line 6: undefined method 'each' for Tuple(Int32 | UInt8, String):Class
@asterite
Copy link
Member

Should we add Tuple.types then?

@bcardiff
Copy link
Member

Something like Tuple.types seems like a good addition (or restoration).
I think that NamedTuple.types should also exist returning a named tuple of key -> type.

But then, if we think in the broader feature, we are looking for a way to get the type arguments of generic types in runtime. Tuple and NamedType are special cases because they don't exhibit in their declaration the T argument, but it is still there.

So if we add expr.class.generic_arguments for all generic types might be the more complete solution. (yet, if we add just for tuple and named tuple i'm fine).

The generic_argument would return a tuple when positional arguments are used or a named tuple when named arguments are used (in well, named tuples). For cases like StaticArray though, the returning tuple will contain the length numeric argument.

@oprypin
Copy link
Member Author

oprypin commented Sep 10, 2017

The future planning is all fine but is it correct that Tuple#types is entirely useless at the moment?

@bcardiff
Copy link
Member

I agree @oprypin . BTW a shorter implementation would be Tuple.new(*{{T}})

@bcardiff bcardiff added this to the Next milestone Sep 15, 2017
@bcardiff bcardiff added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib labels Sep 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:stdlib
Projects
None yet
Development

No branches or pull requests

3 participants