/ / ruby ​​condition gibt nil statt true / false zurück - ruby, encoding, byte

ruby condition gibt null statt wahr / falsch zurück - ruby, encoding, byte

Ich verwende Ruby 2.0.0p451 (2014-02-24) [x64-mingw32] und ich bin auf etwas gestoßen, das zuvor in der 1.9.x-Version funktioniert hat und hier nicht funktioniert. Ich habe mich gefragt, ob sie das Verhalten geändert haben, ob ich etwas falsch mache oder ob dies ein Fehler ist.

Ich sende ein Byte durch eine Socket xFF und ich empfange es am anderen Ende, aber wenn ich versuche, es mit sich selbst zu vergleichen (was wahr sein sollte), wird die erwartete Ausgabe nicht zurückgegeben.

Beispiel, ich schicke die Zeichenfolge xFFx50x00usernamex00555x00 und ich erhalte es gut am anderen Ende, aber wenn ich versuche, das erste Byte mit sich selbst zu vergleichen, verhält sich die Bedingung falsch.

Hier einige Codebeispiele, damit Sie sehen können, wie ich mit den Daten umgehe (mit relevantem Code).

class PacketReceiver
def setpacket( buffer ); @buffer = buffer; end
def getbyte
byte = @buffer[0..0]
@buffer = @buffer[1..-1]
byte
end
end

def parsepacket(packet)
#@receiver = PacketReceiver.new #defined elsewhere in code
@receiver.setpacket packet

return false unless @reciever.getbyte.eql? "xFF" #the bugged line

#Everything works beyond this point
packet_id = @reciever.getbyte

case packet_id
when "x50"
return sid_requesting_config
when "x51"
sid_requesting_data_response
when "x52"
sid_keep_alive_response
else
puts "failed"
return false
end
return true
end

In 1.9.X This unless Aussage funktionierte gut. Beim Debuggen der Daten werden die Daten von zurückgegeben @receiver.getbyte ist zwar "xFF", aber aus irgendeinem Grund das eql? Der Vergleich gibt "false" statt "true" zurück, sodass die Funktion "false" zurückgibt. Wenn ich dieses Byte aus der Nachricht entferne und die Überprüfung entferne, wird auch der Rest des Codes aufgerufen getbyte Methode funktioniert gut.

Auch wenn ich das Byte in "x55" und nicht in "xFF" die Bedingung verändere unless Aussage funktioniert wie es sollte.

Ich bin nicht sicher, was los ist. Ist xFF für etwas reserviert?

Antworten:

0 für die Antwort № 1

Ich vermute das buffer ist binär codiert (d. h. buffer.encoding ist ASCII-8BIT). Das bedeutet, dass dies geschieht:

c  = @receiver.getbyte # c also has binary encoding
ff = "xff"            # ff is probably utf-8
c.eql? ff              # comparing strings in different encodings gives you `false`

Stattdessen sollten Sie einfache numerische Vergleiche durchführen:

@receiver.getbyte.getbyte(0) == 255

Oder noch besser, modifizieren getbyte eine ganze Zahl zurückgeben

Ich denke, Ihre 1.9.X-Version funktionierte meistens aus Versehen, Sie hätten schon immer einen einfachen numerischen Vergleich verwenden sollen.

Denken Sie daran, dass sich in Ihrem Puffer Bytes (wie 0xFF und 0x00) befinden, die in utf-8-Zeichenfolgen nicht gültig sind. Sie können verwenden force_encoding auf Scheiben des Puffers für die Teile, die utf-8-Zeichenketten sind. Vielleicht möchten Sie es sich ansehen String#unpack auch.


Beachten Sie, dass ich auf die Ruby 2.0.0-spezifischen Dokumente verlinke, die der aktuell verwendeten Ruby-Version entsprechen.