Crystal::Macros
module Crystal::Macros
Overview
The Macros module is a fictitious module used to document macros and macro methods.
You can invoke a fixed subset of methods on AST nodes at compile-time. These methods are documented on the classes in this module. Additionally, methods of the Macros
module are top-level methods that you can invoke, like #puts
and #run
.
Defined in:
compiler/crystal/macros.crInstance Method Summary
- #`(command) : MacroId
Executes a system command and returns the output as a
MacroId
. - #compare_versions(v1 : StringLiteral, v2 : StringLiteral) : NumberLiteral
Compares two semantic versions.
- #debug(format = true) : Nop
Outputs the current macro's buffer to the standard output.
- #env(name) : StringLiteral | NilLiteral
Gets the value of an environment variable at compile-time, or
nil
if it doesn't exist. - #p(expression) : Nop
Same as
#puts
. - #puts(expression) : Nop
Prints an AST node at compile-time.
- #raise(message) : NoReturn
Gives a compile-time error with the given message.
- #run(filename, *args) : MacroId
Compiles and execute a Crystal program and returns its output as a
MacroId
. - #skip : Nop
Skips the rest of the file from which it is executed.
- #system(command) : MacroId
Executes a system command and returns the output as a
MacroId
.
Instance Method Detail
def `(command) : MacroIdSource
Executes a system command and returns the output as a MacroId
. Gives a compile-time error if the command failed to execute.
def compare_versions(v1 : StringLiteral, v2 : StringLiteral) : NumberLiteralSource
Compares two semantic versions. Returns -1
if v1 < v2
, 0
if v1 == v2
and 1
if v1 > v2
.
{{ compare_versions("1.10.0", "1.2.0") }} # => 1
def debug(format = true) : NopSource
Outputs the current macro's buffer to the standard output. Useful for debugging a macro to see what's being generated. Use it like {{debug()}}
, the parenthesis are mandatory.
By default, the output is tried to be formatted using Crystal's formatter, but you can disable this by passing false
to this method.
def env(name) : StringLiteral | NilLiteralSource
Gets the value of an environment variable at compile-time, or nil
if it doesn't exist.
def raise(message) : NoReturnSource
Gives a compile-time error with the given message.
def run(filename, *args) : MacroIdSource
Compiles and execute a Crystal program and returns its output as a MacroId
.
The file denote by filename must be a valid Crystal program. This macro invocation passes args to the program as regular program arguments. The program must output a valid Crystal expression. This output is the result of this macro invocation, as a MacroId
.
The #run
macro is useful when the subset of available macro methods are not enough for your purposes and you need something more powerful. With #run
you can read files at compile time, connect to the internet or to a database.
A simple example:
# read.cr puts File.read(ARGV[0])
# main.cr macro read_file_at_compile_time(filename) {{ run("./read", filename).stringify }} end puts read_file_at_compile_time("some_file.txt")
The above generates a program that will have the contents of some_file.txt
. The file, however, is read at compile time and will not be needed at runtime.
NOTE the compiler is allowed to cache the executable generated for filename and only recompile it if any of the files it depends on changes (their modified time). This is why it's strongly discouraged to use a program for #run
that changes in subsequent compilations (for example, if it executes shell commands at compile time, or other macro run programs). It's also strongly discouraged to have a macro run program take a lot of time, because this will slow down compilation times. Reading files is OK, opening an HTTP connection at compile-time will most likely result if very slow compilations.
def skip : NopSource
Skips the rest of the file from which it is executed. Typical usage is to skip files that have platform specific code, without having to surround the most relevant code in {%...%}
macro blocks.
Example:
# sth_for_osx.cr {% skip() unless flag?(:darwin) %} # Class FooForMac will only be defined if we're compiling on OS X class FooForMac end
def system(command) : MacroIdSource
Executes a system command and returns the output as a MacroId
. Gives a compile-time error if the command failed to execute.
© 2012–2017 Manas Technology Solutions.
Licensed under the Apache License, Version 2.0.
https://crystal-lang.org/api/0.22.0/Crystal/Macros.html