From: Ross Bamford Date: 2006-01-06T19:03:14+09:00 Subject: Re: Attribute writers On Fri, 06 Jan 2006 09:16:50 -0000, 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? > Is this any help? irb(main):006:0> s = "123145992348241110111 11 11 1 1111 3331 1" => "123145992348241110111 11 11 1 1111 3331 1" irb(main):007:0> s[0..2] => "123" irb(main):008:0> s[0..2] = '777' => "777" irb(main):009:0> s => "777145992348241110111 11 11 1 1111 3331 1" > 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! > As far as I'm aware you can't do indexed attribute writers. You can of course do: def []=(idx, val) puts "at #{idx} = #{val}" end But Ruby won't have it if you prefix the [] with a name. What I think I'd do is just remove the writer (for this purpose) and have ascii return a String. The you can do: if currentRespondent[0..2] == '777' currentRespondent.ascii[0..2] = "123" end (since String's [] is pretty flexible as I showed above) But I have a feeling I may have missed something in your question. Is that helpful? -- Ross Bamford - rosco@roscopeco.remove.co.uk