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.

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

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