2015-06-25 155 views
3

我知道Crystal在编译时有它的宏定义代码的系统,但有可能除此之外运行代码吗?在编译时运行任意代码

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

puts "foobar" 

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

回答

6

是的,我们可以!在run macro methodsystem macro method的帮助下。

我们已经编译随机问候到程序每次它是构建一个例子:

greetings.txt:

Hello 
Hey 
Hi 

greeting.cr:

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

招待员。 cr:

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

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

+3

谢谢,这似乎这样的伎俩。有点困惑,因为在'greeting.cr'中的代码编译时(或者根本没有)输出'puts'输出,但是我会修改一下并阅读你给出的链接。 –

+2

......我明白了。它返回最终语句的结果而不是输出。有意义,完美的作品。再次感谢! –

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

+2

非常好,谢谢! –

+4

'{{debug()}}宏也适用于调试宏。它打印生成的水晶代码。 '{{puts}}'可以用于在编译时向开发者输出消息(例如:弃用消息)。 –