How can I keep references to numeric values in a Hash in Ruby? Say I have
h={"a"=>1, "b"=>2}
c=h["a"]
Wh开发者_开发技巧en I do
c+=1
I get:
irb(main):079:0> c+=1
=> 2
but
irb(main):080:0> h
=> {"a"=>1, "b"=>2}
so h
has not changed. Can I somehow retain refernces to numeric values and modify them outside the hash h
?
The c
is its own variable, so changing the value of c
doesn't change the value of the item in the hash.
To achieve the effect you want, you can make the hash item an array instead:
h={"a"=>[1], "b"=>2}
c=h["a"] # c is now a reference to the hash item, an array
c[0]+=1 # modifying the array
h # print the hash
(The text after #
is a comment; I am not sure whether they will be ignored by the Ruby console.)
What you need to understand is that there is only ever one '1' (which is why it's a good idea that it be immutable, obviously). It's not like a String where two variables could share a reference to it, and change it under the feet of the other variable, like:
a="foo"
b=a
b.clear
a => ""
To do what you want, you can use the key:
c="a"
h[c]+=1
h=> {"a"=>2, "b"=>2}
Or otherwise use a value that can be changed in-place (as suggested above)
The 'c' should be point to the Key, Numeric is immutable, so you can't change the Numeric value. And ruby prefer to use Symbol for key.
h = {:a => 1, :b => 2}
c = :a
h[c] = 3
puts h # {:a => 3, :b => 2}
If your array value is String, you can:
h = {:a => '1', :b => '2'}
c = h[:a]
c.replace '3'
puts h # {:a => '3', :b => '2'}
or you can create your a class, make the Numeric c can be change.
You are already holding a reference to the numeric value, it's just that the operation you do to it generates a new numeric value instead of changing its own value.
For practicality, we can say that c
holds a reference to the number 1
(although there's a subtle implementation difference between Fixnum
and Bignum
). For c += 1
, you're effectively doing c = c + 1
and the +
operator of the number actually returns a new number. So the variable c
is assigned with the reference to the new number.
This will be a different case if there's a method that can change the the value of the object itself. For example, on String
, the <<
operator changes the value of the object:
h = {"a" => "foo"}
b = h["a"]
b << 'bar'
puts b # foobar
puts h # {"a"=>"foobar"}
But in your case, it is an Integer
and there is no way to change the numeric value of it.
精彩评论