From: Bulat Ziganshin Date: 2002-10-01T13:48:03+09:00 Subject: Re: Where Is Method Call Precedence? Hello William, Monday, September 30, 2002, 8:02:32 PM, you wrote: >> s = "mutable" >> hash = { [s] => "object" } >> s.upcase! >> p hash[["mutable"]] #=> nil WDT> When I first read your code below, it was also obvious to me, since the WDT> original reference to the array [s] in the second line was lost WDT> forever. In the last line, ["mutable"] is really a newly created object, WDT> which is obviously different from the original array object. :)))) you are really thinking ruby way if you tell us about OBJECTS, not VALUES! it is OBVIOUS that hash keys must not change just because we changed some variable used to COMPUTE hash key at some place (to everyone: this is not critique of ruby or reference-oriented semantic ;) WDT> But then, toying with your idea, I found this: WDT> # ruby 1.6.7 (2002-03-01) [i686-linux] WDT> s = "mutable" WDT> arr = [s] hash = { arr =>> "object" } WDT> s.upcase! p hash[arr] #=>> nil WDT> This is really surprising to me! Is this the expected behavior in WDT> Ruby? Because in Python, using an array as a hash key is forbidden in the WDT> first place (syntax error, I guess), while Ruby simply allows us to do so. WDT> Any idea, anyone? (I really thought before that the hash key were WDT> actually just the object ID in Ruby.) all ruby variables just hold REFERENCES to objects in heap (except for fixnum/true/false/nil). when you assign variable or call the method, just refernce (4 bytes) is copied. so, from this moment you have 2 references to the same object, and when you change object thorough one reference, you will see change thorough another references a="xy" b=a a.upcase! p a,b def f(x); x[0] = '-'; x end c=f(b) p a,b,c >> it's a well-known theoretical problem. call/asign by reference or by >> value, and mutable objects versus non-modified and ruby has the best solution i know of this problem -- Best regards, Bulat mailto:bulatz@integ.ru