Macro Help Determining Type

I have a hash which stores a few different object types but with the way the application is structured, given a key it will always return a certain object type. That key may be missing through. I want to wrap it with accessors that simplify that type juggling.

Here is my macro:

private macro section_getter(name, type=String)
  def {{name.id}}
    ret = @data[{{name.stringify.capitalize}}]?.try &.as {{type}}

    {% if type.stringify.starts_with? "Array" %}
      ret ||= [] of {{type.type_vars.first}}
    {% end %}

    ret
  end
end

The idea is to call it with something like:

section_getter foo
section_getter bar, Array(Item)
section_getter baz

The idea here is that if I call the foo method I get back either a String or nil. Same with baz. But bar is different. It always returns an array although it might be an empty array. Basically if type is not an array then the method return an object of that type or nil. If the type is an array then it always returns an array but that array may be empty if the underlying hash didn’t have that key.

What I don’t really love is the if statement in the macro. I feel like I should have:

{% if type.is_a? Array %}

But that doesn’t work. I’ve tried various other things and none of them work so my hacky convert it to a string and see if it starts with Array is the best I can do. It works but it seems like there should be a better way.

Try type <= Array.

Check How to append to an Array that is a default Value of a Hash? - #5 by bcardiff and the referenced github issue for what I think is a related thing you are trying to do. :-)