Can I define a compile-time variable in a macro?

class UserHandler
end

macro register(cls)
  %k = ""
  {% for c, index in cls.stringify.chars %}
    {% if index != 0 && c.stringify =~ /[A-Z]/ %}
      %k += "_" + {{c}}
    {% else %}
      %k += {{c}}
    {% end %}
  {% end %}

  %k.downcase
end

register UserHandler # -> "user_handler"

Play code: https://play.crystal-lang.org/#/r/72ws

I know that %k is a runtime variable, and my requirements can actually be done at compile time. How can I avoid this kind of overhead?

https://play.crystal-lang.org/#/r/72xy

Like so. Just do like {% k = "" %}.

But your whole macro is a bit unnecessary. Can accomplish the same outcome by doing

macro register(cls)
  {{cls.stringify.underscore}}
end

However, this would have to be altered slightly depending on how you want to handle classes in modules. I.e. just the class name, or also include the module path.

1 Like

Thank you for your answer to the question.
Thank you for telling me the underscore method.
Thanks for your suggestion!

:+1::+1::+1:

1 Like