13 Mar 2006 09:57

spacer pack and unpack broken on Tiger's Ruby

Imagine my surprise when my iBook told me that network byte order had been changed to little-endian:

irb(main):001:0> [1].pack 'n'
=> "\001\000"

Just to make sure I wasn't losing my edge, I ran the same code on my x86 box:

irb(main):001:0> [1].pack 'n'
=> "\000\001"

Array#pack (and String#unpack) are broken on OS X Tiger's shipped Ruby. After some research, it appears the reason is that they cross compiled it from x86, and when built Ruby remembers the architecture for the purposes of the NnVv formatters of pack/unpack. The purported remedy is to build your own Ruby. I reported the bug to Apple, I have a small hope that eventually they'll update it. In the meantime ruby programs using pack can either work around this or require users to install a fixed Ruby.

Update: Here's a workaround with thanks to Paul Battley:

# Test for broken pack/unpack
if [1].pack('n') == "\001\000"
  class String
    alias_method :broken_unpack, :unpack
    def unpack(spec)
      broken_unpack(spec.tr("nNvV","vVnN"))
    end
  end
  class Array
    alias_method :broken_pack, :pack
    def pack(spec)
      broken_pack(spec.tr("nNvV","vVnN"))
    end
  end
end

[/mac] permanent link

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.