Open Blacksmoke16 opened 11 months ago
Since Annotation#named_args
always returns a fresh NamedTupleLiteral
even in 1.0.0, you could do this:
macro foo(__named_tuple = @[UNUSED])
{{ x = __named_tuple.named_args }} # => {}
{{ x.class_name }} # => "NamedTupleLiteral"
{% x[:d] = 1 %}
{{ x }} # => {d: 1}
{{ __named_tuple.named_args }} # => {}
end
foo
Oo that's a good find! For my use case tho, I don't have access to a macro parameter like that. But I did test it and:
annotation UNUSED; end
@[UNUSED]
module Test; end
...
Test.annotation(UNUSED).named_args
Seems to work the same so you could get a new one anywhere.
Tho in one place outside of macro code I still need to do:
CONFIG = {parameters: {__nil: nil}} # Ensure this type is a NamedTupleLiteral
But this is a slightly diff use case than this issue is for at least.
Hash and NamedTuple literals in macro land are a bit unique in that they are both mutable data structures, but with a few key differences:
c = {__nil: nil}
, but because https://github.com/crystal-lang/crystal/issues/8849 is still TBD you're kinda stuck with dealing with that key/value.Not really sure what I'm proposing, but at least wanted to start a discussion on possible ways to make these types easier to work with. Whether that be normalizing the key access between the types, or allow creating empty namedtuple literals, or something else.