ruby - 在ruby中读取后变量的内容发生变化

标签 ruby sinatra

我是 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/

相关文章:

ruby - 使用 .insert 字符串方法写入文件

sinatra - 我在datamapper中尝试 “all”方法时发生错误

ruby - 如何正确国际化 Sinatra 页面?

ruby - Sinatra 中的 Postgresql 连接

ruby - sinatra,rack auth basic 和从文件中查找

ruby - 数组大小太大 - ruby

ruby 嵌套哈希

ruby-on-rails - 运行 Linux 命令 "from" 'RAILS_ROOT/config/environments/production.rb' 文件

ruby - 在 Linux 上使用 skript 同步两个目录的特殊类型

ruby - 使用 Sinatra : Signed Cookie (with Rack) 的 Facebook Canvas 身份验证