From: Caleb Clausen Date: 2010-10-03T12:57:48+09:00 Subject: Re: Pass by reference and copy on write On 10/2/10, Josh Cheek wrote: > On Sat, Oct 2, 2010 at 8:56 PM, Caleb Clausen wrote: > >> Rather than inventing a new class to do pass-by-reference, I'd >> advocate using one that already exists: Array. So then you could call >> the method like this: >> >> a = [1] >> b = [2] >> puts "initially: a=#{a[0]}, b=#{b[0]}" >> change_value a , b >> puts "after: a=#{a[0]}, b=#{b[0]}" >> >> > Interestingly, that would bring it very much in line with the C example, > since pointers and arrays in C are (almost) the same thing. Right. I'm just a C hacker at heart. > It's just that in the case of Fixnums (and a few other things) it is >> not possible to have references at all; such objects are always stored >> (and passed) by value > > If it were pass by value, I would expect it to make a new object each time > it passes that object. It does make a new object when you pass a Fixnum as a parameter; the Fixnum is copied into a different cell in memory. Fixnums are compressed so that the Fixnum value is stored within the reference to it. So I guess Fixnums are kinda value and reference all wrapped up in one burrito. Convinced? I'm not sure I am. > def mutate_myvar(remote) > remote.instance_eval { @myvar = "bye" } > end > def oid(remote) > remote.send :object_id > end > local = 1 > local.class # => Fixnum > local.instance_eval { @myvar = "hi" } > local.instance_eval { @myvar } # => "hi" > mutate_myvar(local) > local.instance_eval { @myvar } # => "bye" > local.send(:object_id) == oid(local) # => true You have just demonstrated that Fixnums are not immutable after all, since their instance variables can be changed. I had forgotten that. Deliberately. You do realize, don't you, that instance variables on Fixnums (and Symbols, and nil/false/true) is an evil hack, to be avoided by all sane and reasonable code? All instances of the Fixnum 1 share the same set of instance vars... ulh. > So it doesn't make a new object, which means that we are dealing with the > same object after passing it. I would expect this is because the method > received a reference to the same object that main is using, and would thus > expect it to be pass by reference. I would agree that it behaves like pass > by value, because it has no mutators.