Inside a crystal macro the rules change, instead of executing its code it
returns it, interpolating the stuff between {}. Parameters are not evaluated,
they are received as AST nodes. When we invoke a macro, it gets replaced by
its expansion (the result of its execution) at compiletime, not runtime
macro vo_initialize(*attributes)
def initialize({{attributes.join(", ").id}})
{% for attribute in attributes %}
@{{attribute.var}} = {{attribute.var}}
{% end %}
end
end
macro vo_readers(*attributes)
{% for attribute in attributes %}
def {{attribute.var}}
@{{attribute.var}}
end
{% end %}
end