在编译时运行任意代码

时间:2015-06-25 20:10:40

标签: compile-time crystal-lang

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

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

puts "foobar"

或者对于一个更严肃的例子,我们可以读取和写入运行编译器的文件系统吗?

2 个答案:

答案 0 :(得分:6)

是的,我们可以!借助run macro methodsystem 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进行编译,您会注意到编译后的二进制文件的输出保持不变,但每次重新编译时都是随机的。

答案 1 :(得分:5)

作为Jonne所说的额外答案,您可以在编译时使用puts输出内容,但在宏内部。例如:

{{ puts "foobar" }}

您会注意到编译期间会打印“foobar”,但可执行文件不会执行任何操作(尝试使用crystal build foo.cr; ./foo

当然,只是在编译时输出一些内容并不是很有用,但是当你想快速调试一些宏时,这很有用。

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