On Aug 6, 2006, at 11:29 PM, Meino Christian Cramer wrote: > My first idea was to define an Hash which maps an input range > to an index. To this index it is easy to add an offset. The > second step would be an array, which maps the new calculated index > (old index + offset) to the same range again, but this time > the range was "sorted" by sort{rand} st initialization time. > > But when I do a "a=device.new", what should I return as an obejct > to the caller ??? TWO objects -- the hash AND the array ? The whole point of wrapping something like this is in an object is that these are just internal details user code for the object never needs to worry about. For example, users are going to call your code something like: dev = Device.new( .. ) after = dev.encryrpt(before) All they know is that they are working with a Device. They don't need to worry about Hashes and Arrays. I recommend using a Hash internally in the object. When a problem says "mapping" that usually means Hash. You could build the interface to handle either a Hash or an Integer being passed to the constructor: class Device def initialize(mapping_or_offset) if mapping_or_offset.is_a? Hash @mapping = build_mapping_from_hash(mapping_or_offset) else # offset @mapping = build_mapping_from_integer(mapping_or_offset) end end def encrypt(bytes) # use @mapping here... end private def build_mapping_from_hash(hash) # ... end def build_mapping_from_integer(integer) # ... end end Hope that gives you some fresh ideas. James Edward Gray II