How to refer to a value for a key in a hash

I want to be able to refer to a key in Hash , so if the value for this key changes, then everything refers to it like that

 hash = {} hash[1] = "foo" hash[2] = hash[1] hash[1] = "bar" puts hash[2] # I want this to be "bar" 

Is it possible? Thanks!

+4
source share
2 answers

It's impossible. Here's what happens:

 hash[1] = "foo" # hash[1] is now a reference to the object "foo". hash[2] = hash[1] # hash[2] is now a reference to the object "foo" as well, # since it is what hash[1] is a reference to. hash[1] = "bar" # hash[1] is now a reference to the object "bar" 

Note that the hash[1] assignment does not change the object to which it refers, but rather simply changes the object that it refers to.

In Ruby (like many higher-level languages) you have no pointers and no explicit ability to manipulate links.

However, there are some methods that change, and on String one such example is upcase! . In this example, we see that this method modifies the actual object being referenced without assigning a new object (and therefore the links remain unchanged):

 hash[1] = "foo" #=> "foo" hash[2] = hash[1] #=> "foo" hash[2].upcase! #=> "FOO" hash # => {1=>"FOO", 2=>"FOO"} 
+1
source

Perhaps if you use an object wrapper:

 class A attr_accessor :a def initialize(a) @a = a end end hash = {} hash[1] = A.new("before") hash[2] = hash[1] hash[1].a = "after" puts hash[2].a # => "after 

This is why upcase! works - you do not change the link, but the objects themselves. As far as I remember, a similar mechanism is used in Rails to pass parameters between the controller and the view.

+1
source

Source: https://habr.com/ru/post/1384625/


All Articles