From: Joel VanderWerf Date: 2009-05-15T06:53:17+09:00 Subject: Re: BitStruct technique Chuck Remes wrote: > While working on a problem this morning I came up with an interesting > technique for using the BitStruct gem to produce binary strings. After > some hacking around I discovered I didn't need to use BitStruct at all. > Even so I thought I would share what I learned so the technique doesn't > get lost. > > Imagine you need to construct a binary string from some arbitrary > object. BitStruct allows you to do this in 3 ways: pass a binary string > directly, pass in a hash, or yield a block. It's easy to extend this > mechanism for parsing your own classes by building on the block yield > initialization mechanism. > > hsh = {:a => 1, :b => "foo", :c => "bar"} > > class C < BitStruct > signed :context, 32, "c id" > char :password, 12*8, "pw" > char :usr_name, 12*8, "name" > > # important to initialize these values so the > # block passed to #super is evaluated correctly > initial_value.context = 0 > initial_value.password = '' > initial_value.usr_name = '' > > def initialize message > # parens on #super are important so no args > # are passed up to the parent; if this part fails > # then you missed > super() do |struct| > struct.context = message[:a] > struct.password = message[:b] > struct.usr_name = message[:c] > end > end > end > > c = C.new hsh # very clean! > c.inspect > > In this example I passed in a hash as my message, but the +message+ > variable could have been any object that could be interrogated to > retrieve values for setting the bitstruct fields. I like this technique > because it delegates the responsibility of proper bitstruct > initialization to the class under construction. It nicely encapsulates > that operation which I believe demonstrates the Single Responsibility > principle. > > I hope this is of use to someone someday. > > cr I think I see where you're going with that, but just so others know, the hash-based initialization is simple (though it does require that the hash keys match the field names--and avoiding this is probably the point of your code): require 'bit-struct' hsh = { :context => 1, :password => "foo", :usr_name => "bar" } class C < BitStruct signed :context, 32, "c id" char :password, 12*8, "pw" char :usr_name, 12*8, "name" end c = C.new hsh -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407