ruby条件返回nil而不是true / false

时间:2014-05-03 03:54:14

标签: ruby encoding byte

我正在使用ruby 2.0.0p451(2014-02-24)[x64-mingw32],我发现以前在1.9.x版本中工作的东西在这里不起作用。我想知道他们是否改变了行为,或者我做错了什么,或者这是一个错误。

我在套接字\xFF下发送一个字节,然后在另一端收到它,但是当我尝试将它与自身进行比较时(应该返回true),它不会返回预期的输出。

示例,我发送字符串\xFF\x50\x00username\x00555\x00并且我在另一端接收它很好,但是当我尝试将第一个字节与它自身进行比较时,条件行为错误。

以下是一些代码示例,以便您了解我如何处理数据(浏览相关代码)

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

在1.9.X这unless声明工作正常。调试数据时,@receiver.getbyte返回的数据确实是" \ xFF"但由于某种原因,eql?比较返回false而不是true,导致函数返回false。如果我从消息中删除此字节并删除检查其余代码也调用getbyte方法正常。

此外,如果我将字节更改为" \ x55"而不是" \ xFF"条件unless语句可以正常工作。

我不确定发生了什么。 \ xFF是为某些东西保留的吗?

1 个答案:

答案 0 :(得分:0)

我猜测buffer是二进制编码的(即buffer.encoding是ASCII-8BIT)。这意味着发生了这种情况:

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`

相反,您应该进行简单的数字比较:

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

甚至更好,修改getbyte以返回整数。

我认为您的1.9.X版本大多是偶然的,您应该一直使用简单的数字比较。

请记住,缓冲区中的字节(例如0xFF和0x00)在UTF-8字符串中无效,因此您应该将缓冲区保留为二进制。您可以在缓冲区的片上使用force_encoding作为UTF-8字符串的部分。您可能也想查看String#unpack


请注意,我链接到Ruby 2.0.0特定文档以匹配您当前使用的Ruby版本。