如何从 Crystal 中的字符串变量执行代码?
How to execute code from a string variable in Crystal?
我喜欢 Ruby 中的 eval
,因为它工作起来非常简单:
eval("puts 7 * 8") # => 56
Crystal 中 eval
的等价物是什么?我知道我们可以用宏做类似的事情:
macro eval(code)
{{code.id}}
end
eval("puts 7 * 8") # => 56
但这不适用于运行时值:
a = "yo"
eval("puts #{a}") # => prints nothing
Crystal 是编译型语言,而 Ruby 是解释型语言。这使得在运行时评估代码变得更加复杂。
在你的例子中,宏在编译时展开,所以实际上你的程序只是puts 7 * 8
。换句话说,它之所以有效,是因为代码在编译时是已知的。
但是如果你想执行包含在任意字符串中的代码,它必须调用 Crystal 编译器然后执行生成的可执行文件。这实际上是我们在 Crystal 单元测试中所做的事情。但是标准库中没有包含 "eval" 函数,因为这意味着您编译的程序包含内置的 Crystal 编译器,实际上没有多大意义。
另一个问题是如何传递参数和获取return值。由于您的程序 运行 和评估的代码是不同编译的结果,因此它们可能具有相同类型的不同二进制表示形式。
另一方面,在 Ruby 中使用 eval
通常被认为是一种不良做法,必须尽可能避免。
我喜欢 Ruby 中的 eval
,因为它工作起来非常简单:
eval("puts 7 * 8") # => 56
Crystal 中 eval
的等价物是什么?我知道我们可以用宏做类似的事情:
macro eval(code)
{{code.id}}
end
eval("puts 7 * 8") # => 56
但这不适用于运行时值:
a = "yo"
eval("puts #{a}") # => prints nothing
Crystal 是编译型语言,而 Ruby 是解释型语言。这使得在运行时评估代码变得更加复杂。
在你的例子中,宏在编译时展开,所以实际上你的程序只是puts 7 * 8
。换句话说,它之所以有效,是因为代码在编译时是已知的。
但是如果你想执行包含在任意字符串中的代码,它必须调用 Crystal 编译器然后执行生成的可执行文件。这实际上是我们在 Crystal 单元测试中所做的事情。但是标准库中没有包含 "eval" 函数,因为这意味着您编译的程序包含内置的 Crystal 编译器,实际上没有多大意义。
另一个问题是如何传递参数和获取return值。由于您的程序 运行 和评估的代码是不同编译的结果,因此它们可能具有相同类型的不同二进制表示形式。
另一方面,在 Ruby 中使用 eval
通常被认为是一种不良做法,必须尽可能避免。