我是 ruby 的新手(昨天开始),我正在尝试使用 sinatra 来构建 API。我遇到了一个让我一头雾水的问题:
post '/login' do
if request.body.read.length == 0
halt 400 # bad request
else
body = JSON.parse(request.body.read)
end
end
当我执行这段代码时,我遇到了一个错误,因为我试图用 body = JSON.parse(request.body.read)
解析一个空字符串。事实上,我必须将 request.body.read
保存在另一个变量中才能使用它两次(或更多次),因为它就像 request.body
在第一次使用。
这让我想起了 borrows with rust,但在这里我没想到,也无法在 google 上表达它以找到任何文档。 谁能给我解释一下发生了什么以及为什么 request.body
只能读取一次?
对于遇到同样问题(我们永远不知道)的人,这里是解决方法:
post '/login' do
body = request.body.read
if body.length == 0
halt 400 # bad request
else
body_json = JSON.parse(body)
end
end
我听说过 IO 对象,但我仍然无法深入研究。
最佳答案
request.body
是一个输入流。
流是计算中的一种基本数据结构,其中数据按顺序提供并且必须按顺序使用。例如,通过 Internet 发送的数据是一个流。
流处理非常强大,因为它允许您处理大于机器内存的数据,例如 Netflix 上的电影会流式传输到您的计算机,因此它们永远不必存储整部电影,而只需存储当前帧。
通常流只能被读取一次。如果您想多次访问流数据,则必须对其进行缓冲。这就是您使用 body = request.body.read
所做的,干得好!
有些流是可倒带的。碰巧 Sinatra 中的 request.body
是可倒带的,因此您可以将它倒带到开头并再次阅读。
request.body.read
request.body.rewind
request.body.read # => returns the content again
关于ruby - 在ruby中读取后变量的内容发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41353988/