Do not add the second hash to an array

0

I am creating an array of hashes that are automatically added with a input , the problem is that when I want to add a second user it deletes the data from the first one .

people = {}
data = []

puts 'Write your name'
name = gets.chomp.capitalize
people[:name] = name
puts 'Write your age'
age = gets.chomp.to_i
people[:age] = age

print people

data << people
print data
    
asked by frtgu34 08.07.2017 в 21:43
source

1 answer

0

Why do you erase the first user's data?

The problem is that you modify the keys of the hash people after asking again and, when adding it to the array data , you are simply adding a reference more to the same object hash .

Consider the following code:

data   = []
people = {}

people.object_id
#=> 70339446093100

people[:name] = "Gerry"
people
#=> {:name=>"Gerry"}

people.object_id
#=> 70339446093100

data << people
#=> [{:name=>"Gerry"}]

data[0]
#=> {:name=>"Gerry"}

data[0].object_id
#=> 70339446093100

As you can see, the hash people is always the same object (the id does not change), including the reference inside the array data .

Let's continue with the script, changing the key name in the hash people :

people[:name] = "Alejandra"
people
#=> {:name=>"Alejandra"}

data
#=> [{:name=>"Alejandra"}]

data[0]
#=> {:name=>"Alejandra"}

We can see that, by changing the key name within the hash people , you are changing the name in all objects that refer to that hash , including the array data .

Let's follow the sequence by adding the hash people to the array data (as you do in your code):

data << people
#=> [{:name=>"Alejandra"}, {:name=>"Alejandra"}]

data[0].object_id
#=> 70339446093100

data[1].object_id
#=> 70339446093100

Again you may notice that the object is still the same , so the array has two elements that refer to the same object and, as a consequence, when modifying the hash people you see the change in both.

Finally, you can confirm that it is still a reference to the same code by changing the information directly in data :

data[0][:name] = "Diaz"

data
#=> [{:name=>"Diaz"}, {:name=>"Diaz"}]

people
#=> {:name=>"Diaz"}

The result is exactly the same, you modified the original object, so both the value of data[1] and people change.

How do I resolve it?

What you have to do is generate a new hash (instead of modifying the same hash keys) every time you ask and add it to the array data ; for example:

data = []

puts 'Write your name'
name = gets.chomp.capitalize
puts 'Write your age'
age = gets.chomp.to_i

data << { name: name, age: age }

As you can see, instead of using a variable with the hash that you want to add to the array , you simply create a new hash ( ie { name: name, age: age } ) with the information previously provided by the user and added as a new element to the array .

You can see here an example of this code in action.

Or, if you still want it, you can use a variable to save the hash , but you must modify the entire variable (not just the keys) to create a new object; for example:

data = []

puts 'Write your name'
name = gets.chomp.capitalize
puts 'Write your age'
age = gets.chomp.to_i
people = { name: name, age: age }

print people

data << people
print data

You can see here an example of this code in action.

    
answered by 08.07.2017 / 22:10
source