Ruby / Rails中有没有办法执行字符串中的代码?

时间:2009-07-27 15:36:29

标签: ruby-on-rails ruby scripting

所以我有一个不同代码示例的数据库(读取片段)。 代码示例由用户创建。 Rails有没有办法执行它?

例如,我的数据库中包含以下代码(id = 123):

return @var.reverse

我有办法执行它吗?类似的东西:

@var = 'Hello'
@result = exec(CodeSample.find(123))

结果就是'olleH'

3 个答案:

答案 0 :(得分:79)

您可以使用eval

code = '@var.reverse'
@var = 'Hello'
@result = eval(code)  # => "olleH"

但这样做要非常小心;您正在为该代码提供对系统的完全访问权限。试试eval('exit()'),看看会发生什么。

答案 1 :(得分:14)

eval答案(这是正确的答案)我想补充一下:给你一份Pickaxe Book(Programming RubyProgramming Ruby 1.9,取决于你的Ruby版本)和阅读名为“在安全中锁定Ruby”的章节。这一章是关于Ruby的安全级别和受污染的对象,本章打开了完全您的用例以及为什么需要对此感到偏执。

答案 2 :(得分:2)

如果您的用例非常有限或限制用例,还可以使用另一种方法。

我不得不使用这种方法来允许用户动态指定相对时间,例如3.months.ago

我使用正则表达式来清理来自用户的输入

PERMITTED_OPERATIONS = /^\{\%([1-9]\.(day|year|month|hour|minute)(s\.|\.)ago|Time\.now)\%\}$/
def permit?(operation)
  return !PERMITTED_OPERATIONS.match(operation.to_s).nil?
end

您可以扩展正则表达式以允许from_now或者为允许的操作创建一个正则表数组并循环它。

欢迎任何关于这种方法的评论。