Search code examples
metaprogrammingcrystal-lang

How to check if a constant is defined in Crystal


I need to verify if a constant is defined to do a conditional.

I was trying this but "defined" method not exists on this language:

if defined(constant)
  value = :foo
else
  value = :bar
end

Solution

  • You can use macro and TypeNode#has_constant?:

    FOO = 1
    
    value = nil
    {% if @type.has_constant? "FOO" %}
      value = :foo
    {% else %}
      value = :bar
    {% end %}
    
    pp value #=> :foo
    

    Or even better, you can write a short custom macro for this:

    macro toplevel_constant_defined?(c)
      {{ @type.has_constant? c }}
    end
    
    pp toplevel_constant_defined? "FOO" # => true
    pp toplevel_constant_defined? "BAR" # => false
    

    Note: as mentioned by Jonne Haß, you only ever should need this in advanced macro programming, everywhere else it's a huge code smell, regardless of the language used.