0

According to this question, ruby is strictly pass-by-value. I came across a case though, which consists of modifying a hash like so:

h = {"one" => ["un", "ein"], "two"=> ["deux", "zwei"]}
h.each { |k,v| v << "overriden"}

resulting in:

{"one"=>["un", "ein", "overriden"], "two"=>["deux", "zwei", "overriden"]}

However, the following behaves differently:

h = {"one" => "un", "two"=> "deux"}
h.each { |k,v| v = "overriden"}

resulting in:

{"one"=>"un", "two"=>"deux"}

How could I have predicted this?

Community
  • 1
  • 1
rpechayr
  • 1,282
  • 12
  • 27
  • Sorry but we've don't this question to death over and over again. – mu is too short Oct 29 '14 at 18:46
  • @muistooshort seriously ? You may have notices that this question was about how I could have predicted this behavior. So really it is not the same question as others. I posted it on stackoverflow to share my experience and allow other people to find examples allowing them to understand the subtleties of pass-by-value pattern. Do you think I could change the title to the question ? – rpechayr Oct 29 '14 at 19:15
  • Yeah, looks like the same thing over and over again to me. You're welcome to get someone else to reopen if you'd like. – mu is too short Oct 29 '14 at 20:39
  • And how would I find this someone else ? – rpechayr Oct 29 '14 at 21:54
  • Do you think the new title does not make it look like the same thing over and over again ? – rpechayr Oct 29 '14 at 21:58
  • @muistooshort I am the kind of person who knows how to find out whether a language is pass-by-value or not. However, I came accross this case today, and thought it was probably a consequence of pass-by-valueness of ruby, but quite surprising though. According to the answer, this was because re-assignment does change the whole reference as opposed to "<<". So again I don't think this just another "is ruby pass-by-value" question, and I changed the title accordingly. – rpechayr Oct 29 '14 at 22:03

1 Answers1

7

If you read the next paragraph in the answer you linked, it says this:

Ruby doesn't have any concept of a pure, non-reference value, so you certainly can't pass one to a method. Variables are always references to objects. In order to get an object that won't change out from under you, you need to dup or clone the object you're passed, thus giving an object that nobody else has a reference to.

The << operator modifies an array in place. You have a reference to the array, the hash has a reference to that array, and when the array changes, they both point at the same array.

When you use = you are assigning a value to a variable. In a way, you are telling the variable to refer to something else, instead of doing something to the thing the variable references.

Linuxios
  • 34,849
  • 13
  • 91
  • 116