On Sat, Oct 2, 2010 at 10:57 PM, Caleb Clausen <vikkous / gmail.com> wrote:

> > 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.
>
>
How about in this case?

def add_ivar(remote)
  remote.instance_eval do
    @ivar = "added in function"
  end
  nil
end

local = 1
add_ivar(local)
local.instance_variables # => [:@ivar]

Here, if I understand you, you are saying that add_ivar's object "remote"
and main's object "local" are not the same object, because it creates a new
object when we pass local as a parameter. However, in add_ivar, we open up
remote and add an instance variable to it. At this point, that ivar should
exist on the add_ivar's "remote" and not on main's "local". When we return,
we pass back nil, just to ensure that add_ivar's "remote" is never an arg,
and should simply be discarded when scope leaves the add_ivar method.
However, back in main, we can see that the ivar that it added does in fact
exist on main's "local". How did it get there, since it is a different
object than the one we mutated?

> 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.
>

Yes, this code is merely intended to illustrate why I think they are
pointing to the same object.