运行 编译时的任意代码

Run arbitrary code at compile time

我知道 Crystal 有其在编译时定义代码的宏系统,但是否可以 运行 代码除此之外的代码?

例如,我们可以这样做,以便它 运行 在编译期间吗?

puts "foobar"

或者举个更严肃的例子,我们可以读写编译器运行ning所在的文件系统吗?

是的,我们可以!在 run macro method or the system macro method.

的帮助下

让我们举个例子,在每次构建时将随机问候语编译到程序中:

greetings.txt:

Hello
Hey
Hi

greeting.cr:

puts File.read_lines("#{__DIR__}/greetings.txt").sample

greeter.cr:

puts {{run("./greeting").stringify}}

使用 crystal build greeter.cr 编译,您会注意到编译后的二进制文件的输出保持不变,但每次重新编译时都是随机的。

作为对 Jonne 所说内容的补充回答,您可以在编译时使用 puts 输出一些内容,但在宏中。例如:

{{ puts "foobar" }}

您会注意到 "foobar" 在编译过程中打印出来,但可执行文件什么也不做(用 crystal build foo.cr; ./foo 试试)

当然只在编译时输出一些东西不是很有用,但是当你想快速调试一些宏时它很有用。

此处记录了 puts 宏方法:http://crystal-lang.org/api/Macros.html#puts%28expression%29%3ANop-instance-method