I’m adding a feature into the Neo4j shard that will let me inject the types of data I expect back from the database because writing the conversion for the compiler gets tedious:
result = connection.execute(query)
result.map do |(user, group)|
{
User.new(user.as(Neo4j::Node)),
Group.new(group.as(Neo4j::Node)),
}
end
Because this is so common, I’ve added a method that lets you pass the types as a tuple and it will build the result as an array of tuples of those types:
connection.exec_cast(query, { User, Group })
And this works fine, I’ve been using it for a while. I’m trying to generalize this so that you can process each result row as you get it back from the DB instead of at the end of the query (so that large query results with millions of rows don’t need to be completely held in memory). I’m using this idea to let you pass a block:
def foo(&block : { Int32 } ->)
yield({12 })
end
foo { |(n)| n }
This works just fine, but since method overloading does not take block args into account and not all calls to exec_cast
will use the same block-arg types, I’m trying to allow them to be injected into the method call so that overloading will occur. Unfortunately, injecting the tuple of types makes it not compile:
def foo(types : T, &block : T ->) forall T
yield({ 12 })
end
foo({ Int32 }) { |(n)| n }
Does anyone have any ideas how to make this work?