views:

82

answers:

3

I'm trying to convert someone's Ruby code into my Python code. The originally developer is no longer with us and I don't know Ruby. Most of his code is easy enough to follow, but some of the following syntax is tripping me up.

Example:

                myTable = ''
                myTable << [ 0, 1, 0, 0, 0, 300].pack('vvvvvv')
                myTable [40, 4] = [41310005 - 5].pack('V')

1) Am I correct to assume that after the 2nd line, myTable is going to hold an array of 6 values specified in the []'s? And is that .pack() similar to Python's struct.pack ?

2) After the third line, is the value on the right going to be stored at position 40 in the array and be 4 bytes long? Is the -5 in the []'s just him being fun or does that hold some special significance?

+3  A: 

You're wrong about the second line, though strangely you're right that it's similar to struct.pack. myTable is a string. Array#pack() returns a string of the packed data (much like struct.pack), and String#<< appends a string to the receiving string. The third line sets 4 bytes at index 40 to be the result of [41310000].pack('V').

Chuck
Fantastic! Thank's so much!
mrduclaw
+1  A: 

No, myTable is a string (it was assigned a string literal). The << operator on strings (and arrays) is the append operator, so you're appending a string to a string. The pack method returns a string, in this case a string of "Short, little-endian byte order." It'll be a string of 6 short integers, not converted to ASCII in any way, just dumped into the string.

Then, part of this string of integers in their native format is being replaced by another value from pack, this turn returning a "Long, little-endian byte order." It's being replaced into the location in the string 40 bytes in, and 4 bytes long.

This is some pretty funky code. Just know that myTable is a string, and that pack is returning numbers in native format.

AboutRuby
Sounds good, this is a great clarification. Thanks!
mrduclaw
+2  A: 

Take a look at the documentation for Array#pack. It converts an array into the string representation of a binary sequence. v is the directive for "Short, little-endian byte order", and V is "Long, little-endian byte order".

The << acts as concatenation when sent to a String object. Since the string is empty before that point, though, myTable could have been immediately initialized to [0, 1, 0, 0, 0, 300].pack('vvvvvv') instead.

String#[m,n]= replaces the substring from index m to m+n.

Daniel Vandersluis
That's excellent, those links to the Ruby docs are totally clutch. Thanks!
mrduclaw
@mrduclaw: BTW: While http://Ruby-Doc.Org/ is the official Ruby Documentation site, it's also butt-ugly and confusing as hell to navigate. http://RubyDoc.Info/ is the new hotness.
Jörg W Mittag