Ruby: ссылка на числовые значения - PullRequest
1 голос
/ 14 июля 2011

Как сохранить ссылки на числовые значения в хэше в Ruby?Скажем, у меня есть

h={"a"=>1, "b"=>2}
c=h["a"]

Когда я делаю

c+=1

, я получаю:

irb(main):079:0> c+=1
=> 2

, но

irb(main):080:0> h
=> {"a"=>1, "b"=>2}

, поэтому hне изменился.Можно ли как-то сохранить ссылки на числовые значения и изменить их вне хеша h?

Ответы [ 4 ]

0 голосов
/ 12 февраля 2013

'C' должен указывать на Ключ, Числовое является неизменным, поэтому вы не можете изменить Числовое значение. А ruby ​​предпочитают использовать Symbol для ключа.

h = {:a => 1, :b => 2}
c = :a
h[c] = 3
puts h # {:a => 3, :b => 2}

Если ваше значение массива - String, вы можете:

h = {:a => '1', :b => '2'}
c = h[:a]
c.replace '3'
puts h # {:a => '3', :b => '2'}

или вы можете создать свой класс, сделать Числовые c можно изменить.

0 голосов
/ 14 июля 2011

Что вам нужно понять, так это то, что существует только одна «1» (поэтому, очевидно, хорошая идея, что она неизменна). Это не похоже на String, где две переменные могут делиться ссылкой на нее и изменять ее под ногами другой переменной, например:

a="foo"
b=a
b.clear
a => ""

Чтобы сделать то, что вы хотите, вы можете использовать ключ:

c="a"
h[c]+=1
h=> {"a"=>2, "b"=>2}

В противном случае используйте значение, которое можно изменить на месте (как указано выше)

0 голосов
/ 14 июля 2011

У вас уже есть ссылка на числовое значение, просто операция, которую вы выполняете с ним, генерирует новое числовое значение вместо изменения его собственного значения.

Для практичности можно сказать, что c содержит ссылку на число 1 (хотя между Fixnum и Bignum есть небольшая разница в реализации). Для c += 1 вы фактически делаете c = c + 1, а оператор + для числа фактически возвращает новый номер. Поэтому переменной c присваивается ссылка на новый номер.

Это будет другой случай, если есть метод, который может изменить значение самого объекта. Например, в String оператор << изменяет значение объекта:

h = {"a" => "foo"}
b = h["a"]
b << 'bar'
puts b # foobar
puts h # {"a"=>"foobar"}

Но в вашем случае это Integer, и изменить его числовое значение невозможно.

0 голосов
/ 14 июля 2011

c - это собственная переменная, поэтому изменение значения c не меняет значение элемента в хэше.

Чтобы достичь желаемого эффекта, вы можете сделатьвместо этого хеш-элемент в массиве:

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

(текст после # является комментарием; я не уверен, будут ли они игнорироваться консолью Ruby.)

...