2

I'm trying to change a specific coordinate, but an array is getting all updated.

The goal is to change the fixed attribute to a single coordinate.

class Case
  attr_accessor :fixed

  def initialize
    self.fixed = false
  end

  def fixed?
    !!fixed
  end
end

def display(arr)
  5.times do |x|
    5.times do |y|
      print arr[x][y].fixed?
      print ' '
    end

    puts
  end
end

# Defining array
arr = Array.new(5){ Array.new(5, Case.new) }

# Displaying the arrays
display(arr)

# Changing value of a single coord
arr[2][3].fixed = true

# Displaying the arrays
display(arr)

Here is the result for the first display call

false false false false false 
false false false false false 
false false false false false 
false false false false false 
false false false false false 

And second display

false false false false false 
false false false false false 
true true true true true 
false false false false false 
false false false false false 

The expected result is:

false false false false false 
false false false false false 
false false false true false 
false false false false false 
false false false false false 

2 Answers 2

6

The problem is that you are placing the same instance in the row multiple times. To make each item in the array a new object change your array definition to the following:

arr = Array.new(5){ Array.new(5) {Case.new}   }

See this question for more info: How to create array of objects?

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

Comments

1

The issue is caused by the way you create the array:

arr = Array.new(5){ Array.new(5, Case.new) }

arr is an array of 5 arrays (Array.new(5) {...}), each of them containing 5 references to the same instance of the Case class (Array.new(5, Case.new)).

There inner arrays and the outer arrays are created in different ways.

The outer array

Array.new(5){ ... }

This code fragment creates an array of 5 elements using a block to initialize each element. The block is executed 5 times (once for each array element). The block creates and returns a new array each time (the inner arrays).

The inner arrays

Array.new(5, Case.new)

This code fragment creates an array of 5 elements and initialize each of them with the same value. The value, returned by calling Case.new once, before Array.new() is an object an Ruby puts 5 references to it into the array returned by Array.new().

The solution

I hope it is clear now how to create an array of 5 different arrays that contain 5 different values. One way is to create the inner arrays the same way as the outer array: by calling Array.new() with one argument (the number of elements) and a block to be executed to initialize each element:

arr = Array.new(5){ Array.new(5) { Case.new } }

Read about Array.new() in the Ruby documentation.

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.