On 10/2/10, Josh Cheek <josh.cheek / gmail.com> wrote:
> On Sat, Oct 2, 2010 at 8:56 PM, Caleb Clausen <vikkous / gmail.com> 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.