我有一个AWS lambda函数,它从浏览器接收用户代码作为字符串,并在沙盒环境中运行eval
,就像在标准REPL中一样。我不是试图插入一个字符串。我想让eval
识别并对字符串执行操作。
我在可以执行的操作方面有所限制。基本的正则表达式替换很酷,但我认为我不能做任何比这更多的事情,但也许我错了。
这适用于基本算术运算,类实例的创建等。但是,它无法正确执行字符串操作。当我通过时:
eval `("3*4")`
它返回12
,这很棒。但是,如果我通过:
eval(""str:" + " test"")
它无法返回"str: test"
。实际上它什么都不返回。
有人建议我逃避双引号。在REPL中,将所有带引号的双引号替换为\"
。
eval("\"str \" + \"test\"") # => "str test"
但是,当我使用AWS尝试此操作时,它会返回"\"str \" + \"test\""
。
我期待着听到您的回复。
你不应该期望eval(""str:" + " test"")
工作。该问题与AWS lambda无关。如果你在自己的机器上尝试使用pry
或irb
,你会得到一个SyntaxError
。那是因为你的翻译无法理解你只是将一个统一的字符串传递给eval。所以你需要转义字符串中的所有引号:
eval("\"str \" + \"test\"")
如果你在没有转义的情况下在REPL中测试它,并且它有效,那么你正在使用的REPL似乎在将它输入到解释器之前改变你的输入。
我似乎找到了一个解决方法。
首先,我将首先澄清我的问题。假设用户输入以下内容:
class Test
attr_accesssor :data
def initialize(data = nil)
@data = data
end
end
其次是
Test.new(4).data
eval
将正确返回4。
然而,现在说,用户反而写了
Test.new("A nice, fine string").data
eval
什么都不会回报。
但是,我注意到,如果我加上.inspect
,如下所示:
Test.new("A nice, fine string").data.inspect
我会被退回A nice, fine string
。
所以我的解决方案是将整个用户代码包装在括号中,然后调用.inspect
。
这是通过以下方式完成的
code = "(" << code << ").inspect"
感谢所有花时间帮助我的人。我非常感谢所有的反馈和建议。
在字符串上使用eval时,需要注意字符串插值:
str = %(This is my String. It's name is string. Now I can eval "Hooray for my string")
eval(str.inspect)
#=> "This is my String. It's name is string. Now I can eval \"Hooray for my string\""
但是这会引起错误
eval(str)
#=> SyntaxError: (eval):1: unterminated string meets end of file
eval(puts str) # will output the string but raise an error after it.
#=> This is my String. It's name is string. Now I can eval "Hooray for my string"
# TypeError: no implicit conversion of nil into String
但这会奏效
eval("puts #{str.inspect}")
#=> This is my String. It's name is string. Now I can eval "Hooray for my string"