I have a macro-land array of NamedTupleLiteral, each representing a field of data to parse for a binary protocol (this is my usecase).
Here is an example:
MACRO_VAR__X_fields = [] of _
macro fixture_fields
{% MACRO_VAR__X_fields << {type: :pad_bytes, by_n: 5} %}
{% MACRO_VAR__X_fields << {type: :card16, name: "data_len", save: false} %}
{% MACRO_VAR__X_fields << {type: :string, name: "important_data", save: true} %}
end
fixture_fields
Now I need to get all the fields that needs to be saved:
{% elems_to_save = MACRO_VAR__X_fields.select { |e| e.keys.includes?(:save.id) && e[:save] } %}
This works (https://carc.in/#/r/3o3w).
But with NamedTupleLiteral#[]?, this could be rewritten as:
{% elems_to_save = MACRO_VAR__X_fields.select { |e| e[:save]? } %}
# or even
{% elems_to_save = MACRO_VAR__X_fields.select &.[:save]? %}
Which feels way better, and simpler to understand.
It is currently missing, and I think it should be added! :smiley:
I can send a PR if you agree
Actually, I just realized that NamedTupleLiteral#[] is NamedTupleLiteral#[]?, so:
{% nt = {a: 1}; puts nt[:non_existant] %} # => nil
I think the documentation should be changed, or the method renamed to what it really is [] => []?.
Documentation should be fixed, but it makes no sense to rename to #[]? without having #[].
Do we have foo? anywhere in macro land? I thought we didn't because it's much more script like and runtime type checking anyway.
@jhass is right: methods are nilable by default in macros, unlike runtime methods that raise by default and may have a nilable alternative.
Close?
Close.
Most helpful comment
@jhass is right: methods are nilable by default in macros, unlike runtime methods that raise by default and may have a nilable alternative.
Close?