2016-12-28 2 views
0

Ich bin neu in Ruby (gestern begonnen) und ich spiele ein wenig mit Sinatra, um eine API zu bauen. Ich trat ein Thema, das mich ohne Anhaltspunkt links:Inhalt der Variablen ändert sich nach dem Lesen in Ruby

post '/login' do 
    if request.body.read.length == 0 
     halt 400 # bad request 
    else 
     body = JSON.parse(request.body.read) 
    end 
end 

Wenn ich diesen Code ausgeführt, ich hatte einen Fehler, da ich eine leere Zeichenfolge mit body = JSON.parse(request.body.read) zu analysieren versucht. Tatsächlich musste ich request.body.read in einer anderen Variablen speichern, um es zweimal (oder mehr) zu verwenden, weil es wie request.body nach der ersten Verwendung "konsumiert" wird.

Das erinnert mich an Anleihen mit Rost, aber hier habe ich das nicht erwartet und kann es nicht auf Google ausdrücken, um irgendwelche Unterlagen zu finden. Kann mir jemand erklären, was passiert ist und warum request.body nur einmal gelesen werden kann?

Für Menschen, die das gleiche Problem haben (wir wissen nie), hier ist das Update:

post '/login' do 
    body = request.body.read 

    if body.length == 0 
     halt 400 # bad request 
    else 
     body_json = JSON.parse(body) 
    end 
end 

ich über IO-Objekte gehört, aber ich kann immer noch nicht weiter in meinen Forschungen gehen.

+0

Sie benötigen mindestens ein weiteres Tag, da das, was Sie gepostet haben, kein reiner Ruby ist. –

+0

Dies ist (zugegebenermaßen leicht) hier abgedeckt: http://www.sinatrarb.com/intro.html#Accessing%20the%20Request%20Object – mwp

Antwort

4

request.body ist ein Eingabestrom.

Streams sind eine grundlegende Datenstruktur in der Datenverarbeitung, bei der Daten nacheinander zur Verfügung gestellt werden und nacheinander konsumiert werden müssen. Zum Beispiel sind Daten, die über das Internet gesendet werden, ein Stream.

Stream-Verarbeitung ist sehr mächtig, weil es Ihnen erlaubt, Daten zu verarbeiten, die größer als ein Gerätespeicher ist zum Beispiel Filme auf Netflix gestreamt werden auf Ihren Computer, so dass sie nie den gesamten Film zu speichern, aber das aktuelle nur Frames.

Typische Streams können nur einmal gelesen werden. Wenn Sie mehr als einmal auf die Stream-Daten zugreifen möchten, müssen Sie sie zwischenspeichern. Was machst du mit body = request.body.read, gut gemacht!

Einige Streams sind rewindbar. Wie es passiert ist die request.body in Sinatra zurückspulbar, so dass Sie es an den Anfang zurückspulen und alles wieder lesen können.

request.body.read 
request.body.rewind 
request.body.read # => returns the content again 
+0

Danke, ich werde mehr über Streams und insbesondere in Ruby lesen, denke ich das ist der Begriff, der in meinen Google-Abfragen fehlte. Frohes neues Jahr! – mgul

+1

Gern geschehen! Sie werden in Ruby nicht immer Streams genannt. Gute Startpunkte sind 'IO' und' Enumerable' und 'Enumerable :: Lazy' – akuhn

Verwandte Themen