def foo(**options)
options.to_h
end
foo # Syntax error in expanded macro: macro_XXX: for empty hashes use '{} of KeyType => ValueType'
I would like to fix it, but I don't know what to_h should return in this case. Thank you.
Oh, it's easy, the method should used NamedTuple.new(...) instead of {...}.
But what would be the type of the resulting Hash in this case? {} of String => Nil perhaps
Oh... it's to_h, I was confused. Mmm... maybe we should check for this case. I think the Hash should be {} of NoReturn => NoReturn.
Probably the error is correct, using to_h on an empty named tuple doesn't make much sense anyway.
But that won't allow you to check existence of a key. Whatever the key of the type you want. Until we support object i would say we should raise or even not compile.
FYI, my use case:
struct NamedTuple
def merge(other)
T.from(to_h.merge(other.to_h))
end
end
class C
@options : NamedTuple(i: Int32, s: String, b: Bool)
DEFAULT_OPTIONS = {i: 1, s: "str", b: false}
def initialize(**options)
@options = DEFAULT_OPTIONS.merge(options)
end
end
If to_h occurs a compile error whenever a tuple is empty, the above code is useless. I'll find another solution. Thank you.
I personally don't think modelling C that way is a good idea. You should have variables @i, @s and @b in C, and make the initialize accept those as named arguments. All those named tuples and hashes will go away, and the code will be simpler and faster.
@asterite Thank you for your advice! I like named arguments but it's not suitable this time :). By the way, I defined to_h? method for my problem like:
struct NamedTuple
def merge(other)
if h = to_h?
if other = other.to_h?
T.from(h.merge(other))
else
self
end
else
raise ArgumentError.new if other.to_h?
self
end
end
def to_h?
{% unless T.empty? %}
to_h
{% end %}
end
end
It's just FYI!
This issue was closed by https://github.com/crystal-lang/crystal/pull/4076.
Most helpful comment
But that won't allow you to check existence of a key. Whatever the key of the type you want. Until we support object i would say we should raise or even not compile.