13 Mar 2006 09:57
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