В рубин, почти каждый объект передается по ссылке. Это означает, что когда вы делаете что-то же просто, как
a = b
, если только не был один из самых простых типов, после этого назначения a
и b
будет указывать на то же самое.
Это означает, что если вы изменяете вторую переменную, то первая влияет таким же образом:
irb(main):001:0> x = "a string"
=> "a string"
irb(main):002:0> y = x
=> "a string"
irb(main):003:0> x[1,0] = "nother"
=> "nother"
irb(main):004:0> x
=> "another string"
irb(main):005:0> y
=> "another string"
irb(main):006:0>
и, конечно же, относится и к хэшей:
irb(main):006:0> a = { :a => 1 }
=> {:a=>1}
irb(main):007:0> b = a
=> {:a=>1}
irb(main):008:0> a[:b] = 2
=> 2
irb(main):009:0> a
=> {:a=>1, :b=>2}
irb(main):010:0> b
=> {:a=>1, :b=>2}
irb(main):011:0>
Если вы не хотите чтобы это произошло, используйте .dup
или .clone
:
irb(main):001:0> a = "a string"
=> "a string"
irb(main):002:0> b = a.dup
=> "a string"
irb(main):003:0> a[1,0] = "nother"
=> "nother"
irb(main):004:0> a
=> "another string"
irb(main):005:0> b
=> "a string"
irb(main):006:0>
для мо st people dup
и clone
имеют такой же эффект.
Так что, если вы пишете функцию, которая изменяет один из его параметров, если вы специально не хотите, чтобы эти изменения будут рассматриваться в коде, который вызывает функцию, вы должны сначала DUP параметр модифицируется:
def test_111(hash)
hash = hash.dup
# etc
end
Поведение вашего кода называется побочным эффектом - изменение состояния программы, которое не является основной частью функции. Побочных эффектов, как правило, следует избегать.
Jörg W Mittag считает, что Ruby является пропускной стоимостью. http://stackoverflow.com/a/6528257/38765 –
Он также признает, что пройденные значения могут быть указателями. С точки зрения плохого кодера это ссылка :) –