Top Level Namespace

Defined in:

Macro Summary

Macro Detail

macro defined?(const) #

This macro accepts a consonant, or a string or symbol of the consonant name. It validates whether the constant is defined, starting at the top level. The value of the constant will be returned if it is defined. If it is not defined, false is returned.

has_db = defined?("DB")

puts "Yes, DB was required." if has_db

macro if_defined?(const, &code) #

This macro accepts a constant, or a string or a symbol of a fully qualified constant name. It validates whether the constant is defined, starting at the top level. If the constant is defined, the code passed to the macro via a block will be instantiated. This permits conditional code evaluation based on whether a constant is defined.

if_defined?("MyClass::FeatureFlag") do
  Log.info { "MyClass::FeatureFlag has been enabled" }
end

macro if_disabled?(env_var, &block) #

Instantiate the code that is passed in the block only if the env_var environment is set to a false value.


macro if_enabled?(env_var, &block) #

Instantiate the code that is passed in the block only if the env_var environment variable is set.


macro if_version?(const, comparison, value, &code) #

This macro accepts a constant, or a string or a symbol of a fully qualified constant name. This constant will be checked for a VERSION or a Version constant, or a #version method under it. If it exists, the value held by that constant, or returned by the #version method is compared with the provided comparison operator to the value, using a SemanticVersion comparison.

if_version?("Crystal", :>, "1.0.0") do
  # Do a thing that only works on Crystal 1.0.0 and later
end

Caveats

If the version is defined using a macro expression (macro code enclosed in a {{ ... }} block), things become more difficult. The compare_versions macro expects to to receive a StringLiteral, SymbolLiteral, or MacroID. If it receives a MacroExpression, it can not evaluate that expression to access the value that it returns, and an exception is thrown when the macro is evaluated. To make things more interesting, there is no way to force that MacroExpression to be expanded from within macro code, making it difficult to access the value. So, for instance, if there were the following version definition:

class Foo
  VERSION = {{ `shards version "#{__DIR__}"`.chomp.stringify }}
end

Then the if_version? macro would not be able to access the value of VERSION because it would be a MacroExpression.

This library does have a workaround for that situation, which will work for simple cases like the above example, however. Essentially, when it encounters a MacroExpression, it reformulates the constant into the local scope, with evaluation wrapped by a {% begin %} ... {% end %} block. Wrapping the macro expression in that way ensures that the value of the expression is already assigned to the constant when the if_version? macro is evaluated. So, if_version? used on Foo, might look like this:

if_version?("Foo", :>, "1.0.0") do
  # Awesome. That's a great version of Foo!
end

The macro will rewrite that to look something like this:

{% begin %}
X__temp_731 = {{ `shards version "#{__DIR__}"`.chomp.stringify }}
{% end %}
if_version?("Foo", :>, "1.0.0") do
  # Awesome. That's a great version of Foo!
end

And this will work.


macro unless_defined?(const, &code) #

This macro accepts a constant, or a string or a symbol of a fully qualified constant name. It validates whether the constant is defined, starting at the top level. If the constant is not defined, the code passed to the macro via a block will be instantiated. This permits conditional code evaluation based on whether a constant is defined.

unless_defined?("SpecialLibrary") do
  Workaround.configure
end

macro unless_disabled?(env_var, &block) #

Instantiate the code that is passed in the block only if the env_var environment variable is set.


macro unless_enabled?(env_var, &block) #

Instantiate the code that is passed in the block only if the env_var environment variable is not set.


macro unless_version?(const, comparison, value, &code) #

See the documentation for #if_version?.