From: Joel VanderWerf Date: 2004-08-14T05:46:26+09:00 Subject: Re: Question: A method for summing several variables Harry Truax wrote: > We initially set all boxes to '' as in this example: > > box1_1 = '' box1_2 = '' . . box12_1 = '' box12_2 = '' etc. . . > > How can I add up a range of boxes without having to specifiy each box > by name? Maybe a nice short method I could call, giving it the > starting box and the step value (sometimes the box numbers differ by > a value other than 1, like my example above where they differ by 2) > and the number of boxes to add. > > Below is a method I tried, but 'box' was not being properly handled - > box could be say, 'box1_10', but I want the value that 'box1_10' > points to, not the .to_f value of the string 'box1_10'. Destructive string methods are your best friends in this case: replace, sub!, gsub!, tr!, etc. As long as you use them, you are operating on the value that box1_10 points to. For example: $SAFE = 3 boxes = Array.new(10) {Array.new(10)} boxes[2][4] = box2_4 = '' box2_4.replace "1.23" p boxes[2][4] # ==> "1.23" boxes[2][4].gsub!(/\d/, "#") p box2_4 # ==> "#.##" boxes[2][4].replace "3.45" p box2_4 # ==> "3.45" And now you can get fancy to make life easier: class Table2D_StringCodedFloats # ok, choose a better name def initialize(boxes) @boxes = boxes end def [](i,j) @boxes[i][j].to_f end def []=(i,j, val) @boxes[i][j].replace val.to_s end end table = Table2D_StringCodedFloats.new(boxes) p table[2,4] # ==> 3.45 table[2,4] = 7 p table[2,4] # ==> 7.0 p box2_4 # ==> "7" table[2,4] += 1 p box2_4 # ==> "8.0" And now you can iterate through the boxes just by using integers in table[i,j]: 10.times do |i| 10.times do |j| table[i,j] = i+j end end p box2_4 # ==> "6" What the heck, let's make it Enumerable: class Table2D_StringCodedFloats include Enumerable def each @boxes.each_with_index do |row, i| row.each_with_index do |value, j| yield i,j,value.to_f end end end end p table.select {|i,j,value| value > 16} # ==> [[8, 9, 17.0], [9, 8, 17.0], [9, 9, 18.0]]