Search code examples
ruby-on-railsrubystringhexpack

Displaying the output of the ruby command .pack("H*")


I have a Rails project which requires working with and manipulating Hex strings. At certain stages I want to print my string for troubleshooting and testing. But I'm getting weird strings in my output. For the following example, I am using Rails 3.1.3 and ruby 1.9.3p385.

Rails console:

["A"].pack('H*')
=> "\xA0"
["0A"].pack('H*')
=> "\n"
["54"].pack('H*')
=> "T"

Run the same commands but this time output it using a puts command:

puts ["A"].pack('H*')
?
=> nil
puts ["0A"].pack('H*')

=> nil
puts ["54"].pack('H*')
"T"
=> nil

How come for ["A"] and ["0A"] when I try to print the results using the puts command it doesn't display the same as just running the command without printing it? And how come ["54"] works correctly?

UPDATE

Above I said that puts ["0A"].pack('H*') isn't displayed correctly but that is not true. ["0A"].pack('H*') returns a newline byte so when you run puts ["0A"].pack('H*') it correctly display the newline byte in string format which appears as nothing but is actually correct.


Solution

  • irb uses the inspect method to produce strings to show and ["A"].pack('H*').inspect is "\xA0". puts calls to_s on its arguments to convert them to strings, String#to_s doesn't do anything useful (unless returning self is useful) so:

    puts ["A"].pack('H*')
    

    is trying to print the byte \xA0 which doesn't represent anything printable in whatever encoding your terminal is expecting (probably UTF-8 these days but maybe ISO-8859-1 or Windows-CP-1252) so you get the standard "I don't know what this is" question mark. puts works fine with ["0A"].pack('H*') and ["54"].pack('H*') because they produce printable characters.