Search code examples
rubymatrixmultidimensional-arrayreturnreturn-value

Generated Matrix value isn't returned properly


def test
    ret = Array.new( @height, [] )
    for y in 0..@height-1
        for x in 0..@width-1
            ret[y][x] = ( Random.rand * 10 ).to_i
        end
        print ret[y]
        puts
    end
    ret
end

When i invoke the test function, i get a random true/false matrix of size width×height, as expected. yet when i look at the return value, i get a matrix which has the contents of the last line printed in every line.

This is printed when i invoke the function:

[8, 3, 7, 9, 6, 2, 2, 2, 1, 5]
[7, 3, 2, 3, 1, 6, 0, 7, 2, 7]
[0, 0, 9, 7, 9, 5, 3, 9, 5, 3]
[7, 7, 8, 1, 6, 3, 3, 7, 9, 9]
[4, 9, 2, 7, 9, 0, 4, 2, 0, 2]
[0, 4, 0, 5, 7, 1, 5, 0, 2, 8]
[0, 5, 6, 9, 1, 8, 8, 3, 6, 2]
[6, 9, 0, 2, 0, 8, 1, 1, 0, 5]
[6, 3, 4, 9, 3, 1, 2, 7, 3, 6]
[5, 6, 6, 4, 4, 0, 0, 0, 4, 3]

Which is what i want.

When i assign the return value of the function to a variable and look at it, i get this however:

[[5, 6, 6, 4, 4, 0, 0, 0, 4, 3],
 [5, 6, 6, 4, 4, 0, 0, 0, 4, 3],
 [5, 6, 6, 4, 4, 0, 0, 0, 4, 3],
 [5, 6, 6, 4, 4, 0, 0, 0, 4, 3],
 [5, 6, 6, 4, 4, 0, 0, 0, 4, 3],
 [5, 6, 6, 4, 4, 0, 0, 0, 4, 3],
 [5, 6, 6, 4, 4, 0, 0, 0, 4, 3],
 [5, 6, 6, 4, 4, 0, 0, 0, 4, 3],
 [5, 6, 6, 4, 4, 0, 0, 0, 4, 3],
 [5, 6, 6, 4, 4, 0, 0, 0, 4, 3]]

Which is just the last printed line over and over again.

My question now is: how can i properly return the matrix from the function to use elsewhere in my code?

i had the function written with ret = [] and in the for loops i used ret.push([]) which then seemed to work for some reason, but that looked very very ugly. I've also tried with different data types, none of which would cause a difference

Expected: The return value should be the same thing as was printed

Actual: The return value is the last line repeated lots of times (see above)


Solution

  • What's happening is here:

    Array.new( @height, [] )
    

    This creates an array containing @height copies of the same array. So each loop when you write to a row, you're actually writing to every row in your matrix.

    Try creating your nested array inside a block, which will ensure each row has a different one.

    Array.new(@height) { Array.new(@width) }
    

    This will call the block for each row of the outer array, ensuring the different rows have different arrays.