【问题标题】:Run arbitrary code at compile time在编译时运行任意代码
【发布时间】:2015-06-25 20:10:40
【问题描述】:

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

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

puts "foobar"

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

【问题讨论】:

    标签: compile-time crystal-lang


    【解决方案1】:

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

    【讨论】:

    • 谢谢,这似乎可以解决问题。有点困惑,因为我在编译期间(或根本没有)从greeting.cr 中的代码中没有得到任何puts 输出,但我会稍微修改一下并阅读您提供的链接。
    • ...啊,我明白了。它返回最终语句的结果而不是输出。有道理并且完美地工作。再次感谢!
    【解决方案2】:

    作为 Jonne 所说的附加答案,您可以在编译时使用 puts 输出一些东西,但在宏内部。例如:

    {{ puts "foobar" }}

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

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

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

    【讨论】:

    • {{ debug() }} 宏也非常适合调试宏。它打印生成的水晶代码。 {{ puts }} 可用于在编译时向开发人员输出消息(例如:弃用消息)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-16
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多