From: Robert Klemme Date: 2006-01-06T19:32:59+09:00 Subject: Re: Attribute writers Michael Judge wrote: > I'm working on a survey system in Ruby and am having a style crisis > with a simple bit of code that has left me paralyzed and unable to > work. > > Respondent data in research surveys is traditionally stored as big > strings of text like this: "123145992348241110111 11 11 1 1111 3331 > 1" > > This was a made up example, in the real world however, there's > sometimes hundreds of thousands of characters in each respondent's > data string. In the stats and analysis section of my program, I'm > working out how to access subsets of these strings in an > object-oriented way. > > Something like this appeals to me and is very readable: > > if currentRespondent.ascii(0..2) == 123 > currentRespondent.ascii(0..2) = 777 > end > > How would one actually implement this? > > class Respondent > def ascii(range) > return @ascii[range] > end > > # doesn't work > def ascii(range)=(value) > @ascii[range] = value > end > end > > currentRespondent = Respondent.new > > This is broken code, as Ruby doesn't like me trying to do "def > a(b)=(c)". There's other ways to accomplish the same purpose (e.g. > def setter(range,value)) but I'm obsessed with the attribute writer > form -- which is just so dang cool. > > Anyone have some light they could spare? > > Argh. I've been struggling with this for a week! Hm, I wouldn't use a string internally at all - at least not if you are trying to do it OO. This is what I'd do: class Results include Enumerable def initialize(from_string = "") @fields = from_string.split(/\s+/).map {|s| s.to_i} end def field() @fields end def each(&b) @fields.each(&b) self end def size() @fields.size end def empty?() @fields.empty? end def to_str @fields.map {|d| d.to_s}.join ' ' end alias :to_s :to_str def to_a() @fields end end You could also simply subclass Array and create appropriate constructors and to_s, to_str methods: class Results < Array def initialize(from_string = "") super( from_string.split(/\s+/).map! {|s| s.to_i} ) end def to_str map {|d| d.to_s}.join ' ' end alias :to_s :to_str end HTH Kind regards robert