/ / ruby ​​condition retorna nil em vez de true / false - ruby, codificação, byte

condição de ruby ​​retorna nil em vez de verdadeiro / falso - ruby, codificação, byte

Eu estou usando o ruby ​​2.0.0p451 (2014-02-24) [x64-mingw32] e eu me deparei com algo que funcionou anteriormente na versão 1.9.x que não funciona aqui. Eu queria saber se eles mudaram o comportamento, ou se estou fazendo algo errado, ou se isso é um bug.

Estou enviando um byte por um soquete xFF e eu recebo do outro lado, mas quando eu tento compará-lo a si mesmo (que deve retornar true) ele não retorna a saída esperada.

Exemplo, eu mando a string xFFx50x00usernamex00555x00 e eu recebo bem do outro lado, mas quando eu tento comparar o primeiro byte para si o condicional se comporta de forma errada.

Aqui estão alguns exemplos de código para que você possa ver como eu estou manipulando os dados (desnatado para o código relevante)

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

Na versão 1.9.X unless declaração estava funcionando bem. Ao depurar os dados, os dados retornados de @receiver.getbyte é de fato "xFF", mas por algum motivo o eql? a comparação está retornando false em vez de true fazendo com que a função retorne false. Se eu remover este byte da mensagem e remover a verificação, o resto do código também chama o getbyte método funciona bem.

Além disso, se eu alterar o byte para "x55" em vez de "xFF", o condicional unless instrução funciona como deveria.

Eu não sei o que está acontecendo. O xFF é reservado para algo?

Respostas:

0 para resposta № 1

Eu estou supondo que buffer é binário codificado (ou seja, buffer.encoding é ASCII-8BIT). Isso significa que isso está acontecendo:

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`

Em vez disso, você deve fazer comparações numéricas simples:

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

Ou melhor ainda, modifique getbyte para retornar um inteiro.

Eu acho que sua versão 1.9.X estava funcionando principalmente por acidente, você deveria estar usando uma simples comparação numérica o tempo todo.

Tenha em mente que você tem bytes em seu buffer (como 0xFF e 0x00) que não são válidos em strings utf-8, então você deve manter seu buffer em binário. Você pode usar force_encoding em fatias do buffer para as partes que são utf-8 strings. Você pode querer olhar para String#unpack também.


Note que estou ligando para os documentos específicos do Ruby 2.0.0 para combinar com a versão do Ruby que você está usando atualmente.