The Crystal Programming Language Forum

Macros and generic type splats

The following code produces a Error: unexpected token: EOF error, and I have no clue as to why.

class Thing(U)
end

class Container(*T)
  def initialize
  end

  def things
    [{% for t in T %}Thing({{ t }}).new, {% end %}]
  end
end

puts typeof(Container(String, Bool, Int32).new.things)

It does look like it expands correctly, given the compiler output

> 1 | Thing(String).new, Thing(Bool).new, Thing(Int32).new,

Need to wrap your array in macro begin/end: Carcin.

2 Likes

Thanks @Blacksmoke16 :sparkling_heart:

Perhaps what I’m truly trying to achieve isn’t really possible in the bounds of macros.

I essentially want an instance var derived from the type splat.

class Container(*T)
  {% begin %}
    getter things : Tuple(
      {% for t in T %}
          Thing({{ t }}),
      {% end %}
    )
  {% end %}

  def initialize
    @things = {% begin %}
      ({
      {% for t in T %}
        Thing({{ t.id }}).new,
      {% end %}
      })
    {% end %}
  end
end

class Thing(U)
end

puts typeof(Container(String, Bool, Int32).new.things)

But a quick check of the compiler issues shows this is not yet possible

Yea, you’d prob have to go the route of record where it takes *args : TypeDeclaration.

1 Like