Ben Giddings wrote: > On Sep 12, 2009, at 00:06, Shawn W_ wrote: >> 04 @data = Array.new(width) { Array.new(height) } > > Create an Array named @data initially with 'width' rows. Set the > value of each element of the array to a new array with 'height' rows. > > If 'width' is 3 and 'height' is 2, @data initially looks like: > > [[nil, nil], [nil, nil], [nil, nil]] I have no problem understanding this bit. An instance variable has been created called "data". The value of this variable is unique for each object created in this class. This variable is equal to an array inside an array; the {} are used to pass the Array.new(height) into each part of the Array.new(width). > >> 07 def [](x, y) >> 08 @data[x][y] >> 09 end > > Create a method to access the elements like so: > > obj[2,0] returns the value of @data[2][0] (here it would be nil) I understand what this is doing but not how it works. As far as I can see it's creating a class Array2D method named [], with parameters x and y. So when you call this method it should look like: 2D_array_obj = Array2D.new(3,8) puts 2D_array_obj.[](1,1) <-- should put whatever is in row 1, column 1. puts 2D_array_obj[1,1] <-- but this is what works to display row 1, column 1. How can you name a method [] when such syntax is used so often elsewhere? How do those 1's get inside the square brackets? Then there is the line: >> 08 @data[x][y] Which is actually: >> 08 a 2D array [x][y] Is the [][] syntax a way of accessing an array inside an array normally? I know you can access a hash inside array using this method. I am even using such code to substitute values into a hash inside my Array2D object like so: 2D_array_obj[x,y]["hash_key"] = new value > >> 11 def []=(x, y, value) >> 12 @data[x][y] = value >> 13 end > > Create a method to set the values: > > obj[1,1] = 4 assigns 5 to the array element at of @data[1][1] > > After which, @data would look like: > > [[nil, nil], [nil, 5], [nil, nil]] I assume "obj[1,1] = 4 assigns 5..." is a typo and should be "obj[1,1] = 5 assigns 5..."? Here we have a different syntax with []= being used. Is []= the name of the method? Now you've explained it I know what this is doing but it's still not clear how it works. > > > I'm not sure what looping logic you're talking about. There are no > loops here, nor any hashes. Array access syntax looks the same as > hashes. If you think there are hashes because of the block braces > { }, it's an unfortunate thing that they share the same syntax, but > generally whether it's a block or an array is pretty clear from the > context. I thought because of the [][] that it was accessing a hash. Isn't this how you access a hash inside an array? >> I'm using this code in a simple 2d array. It was working but then I >> changed all of my ranges from (0...value) to (1..value) [I used ranges >> to populate my 2D array with hashes] I now get the error message: > > > What's probably happening is that you're going beyond the initial size > of the array (width, height). If your array is 2 by 3 and you try to > do: > > x[10, 20] = 5 > > Internally it tries to do @data[10][20] = 5. @data[10] is past the > end of the array, so its value is nil, so @data[10][20] = 5 becomes > nil[20] = 5. > > Giving the error message: > > 11:in `[]=': undefined method `[]=' for nil:NilClass (NoMethodError) > > You could probably fix that by changing the []= method to something > like: > > def []=(x, y, value) > # If @data[x] is nil, create it as an empty array > @data[x] ||= Array.new > @data[x][y] = value > end > > If you do that, you should also fix [] to create missing values too: > > def [](x, y) > # If @data[x] is nil, create it as an empty array > @data[x] ||= Array.new > @data[x][y] > end I think I know what's going wrong. The size of the array hasn't changed, but where I start entering values into the array has, which means there's no room for the last row and column. Basically what I've done is change (0...5), which is 0 1 2 3 4, to (1..5), which is 1 2 3 4 5 - both the same size. But when I use this new range to iterate through my array the first position addressed is now 1; so I'm trying to fit 5 units into a 5 unit box without filling up the space in the box allocated to unit 1. -- Posted via http://www.ruby-forum.com/.