读入 ruby 后变量内容变化

Content of variable changing after read in ruby

我是 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 在第一次使用后得到 "consumed"。

这让我想起了 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