0
out_file = File.open "out_file.txt" , 'w'  do |f|

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

f.puts "matrix test" 

f.puts  " int at [0,2]: #{matrix[0][2]}"
f.puts " int at [2,0]: #{matrix[2][0]}"
f.puts " int at {1,1]: #{matrix[1][1]}" 

above code produces this:

"matrix test
 int at [0,2]: 3
 int at [2,0]: 7
 int at {1,1]: 5"

but this code using the same matrix variable declaration ..

rows = Array(0..3)
cols = Array(0..3)
rows.each do |r|
    cols.each do |c|
         f.puts "row:#{r} col:#{c} = #{matrix[r][c]},"      
     end
end 

produces an error:

undefined method `[]' for nil:NilClass (NoMethodError)

Can anybody please tell me what's going on?

4 Answers 4

1

The problem is your Array(0..3), it is generating an array [0,1,2,3] instead of what you want: [0,1,2].

You actually want to use ... : Array(0...3) => [0,1,2].

Or you could just change the range inside to 0..2 : Array(0..2) => [0,1,2]

Check out the documentation for Range for more information.

Sign up to request clarification or add additional context in comments.

Comments

1

As Tony suggests, using rows=Array(0..2) or rows=Array(0...3) will work for you.

You can also use the range directly and forgo the array creation, like this:

rows = 0...3
cols = 0...3
...

Comments

0

There are 2 types of ranges, the inclusive .. and the exclusive ... which doesn't include the right most digit. A range such as 0..5 will have every number including the 5. (ie. 0,1,2,3,4,5) A range such as '0...5' will have every number excluding the 5. (ie. 0,1,2,3,4). So if you notice your error message,

undefined method `[]' for nil:NilClass (NoMethodError)

You need to begin to wonder what could be running a method on nil. Well, you have this matrix declaration of:

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

So that when this range pops up that is expressed as:

rows = Array(0..3)

It will go through 0,1,2, and also 3. Well, there is no 3 index in that array since your array begins counting at 0 and ends at 2. So when the 3 index hits, the value of it is beyond anything you've declared - it's nil. When you try to run that method on it (to call the spot in the array you want), the error message tells you that you can't run a method (which the [] is actually) on nil.

Paying close attention to your error messages, as well as understanding the 2 types of ranges should help you catch these sorts of errors in the future as well. Leave a comment if this doesn't make total sense.

2 Comments

Many thx. I did have the double dot and triple dot operators confused.
@warwick - Glad to hear it helped. You may want to vote up and accept answers (with the check mark) that helped you the most so other people with a similar question to you can quickly find the best answer. This also helps your reputation as well.
0

The previous answers are right, but I thought I would raise the issue of the approach...

Why are you creating ranged arrays instead of using the actual length of the matrix arrays in question...?

Maybe something like this would remove the need to assume the matrix's composition:

out_file = File.open "out_file.txt" , 'w'  do |f|

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

f.puts "matrix test" 

matrix.length.times do |r|
    matrix[r].length.times do |c|
         f.puts "row:#{r} col:#{c} = #{matrix[r][c]},"      
     end
end 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.