From: Justin Bailey Date: 2006-07-15T00:36:37+09:00 Subject: Unexpected pointer behavior with unpack ------=_Part_37845_31708227.1152891394993 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline I have had the opportunity to work [1] a lot with Ruby's ability to create and manipulate pointers via pack/unpack recently, and have discovered surprising behavior when dealing with nested pointers. I'm interested in other's thoughts on the analysis below. I wasn't able to find a lot of straightforward documentation about this Ruby ability. If I take a string, pack it to a pointer, and then pack that pointer into another string, I lose the ability to retrieve the inner pointer. However, if I make a reference to the "inner" pointer in a local variable, I can still retrieve it. An example is best: puts (inner = ["foo"].pack("P")).inspect # "xxxx" - some 4 byte string puts inner.unpack("P3").first.inspect # "foo" puts (outer = [inner].pack("P")).inspect # "yyyy" - another 4 byte string puts outer.unpack("P4").first.inspect # "xxxx" - first 4 byte string from above puts inner.unpack("P3").first.inspect # "foo" - still can get to inner structure As is shown, I can create a two packed pointers and get access to them through individual variables. However, if I try to access the inner structure from the outer, like so: puts outer.unpack("P4").first.unpack("P3") # ArgumentError - no associated pointer I get an error. Now, I think I understand why this happens - pointers have to be associated with variables. It would be dangerous to unpack to treat any string as a pointer. However, I do think the above is surprising behavior. It took me awhile to understand why my nested structures didn't seem to work. Does anyone else agree with that this is suprising behavior or am I missing something? Justin [1] I needed to call some complex Win32 API functions which took nested structures, that were allocated in Ruby but filled out by the API, and that's what led me down this path. ------=_Part_37845_31708227.1152891394993--