Hi --

On Tue, 7 Dec 2004, itsme213 wrote:

> "Eric Hodel" <drbrain / segment7.net> wrote
> > > Correct. All instance variables of the object are frozen, not the
> > > objects
> > > they refer to.
> >
> > No, the instance variables are not frozen, the instance 'a' of Effable
> > is.
> >
> > #a= modifies a, which is disallowed because a is frozen.
> >
> > You cannot freeze variables, just objects.
> >
> > a = "foo"
> > a.freeze
> > a = "bar"
> 
> I respecfully but heartily disagree. Ruby freezes objects by freezing their
> instance variables. The latter is the fundamental operation.

Ruby freezes objects by... freezing objects.  It doesn't freeze
variables.  Here are some examples, where instance variables are
nowhere to be found but freezing still happens:

  irb(main):001:0> a = []
  => []
  irb(main):002:0> a.freeze
  => []
  irb(main):003:0> a[1] = 1
  TypeError: can't modify frozen array
  irb(main):004:0> s = "abc"
  => "abc"
  irb(main):005:0> s.freeze
  => "abc"
  irb(main):006:0> s << "def"
  TypeError: can't modify frozen string


> a = "foo" # makes the variable a refer to the object "foo"
> 
> a.freeze # makes the instance variables of the object "foo" frozen.

Not exactly; it freezes the object to which 'a' is a reference.  One
of the consequences of that (though not the only consequence) is that
a's instance variables bindings are frozen.  That's why you can't do
this:

> Try this:
> 
> @a = "foo"
> self.freeze
> @a = "bar"

i.e., because you're trying to change what object @a refers to, which
changes the state of 'self' (part of self's state being the bindings
of its instance variables).  However, notice that you *can* do this:

  irb(main):001:0> @a = []
  => []
  irb(main):002:0> self.freeze
  => #<Object:0xbf50da10 @a=[]>
  irb(main):003:0> @a << 1
  => [1]

because the object to which @a refers is not frozen.  

> Ruby just happens to treat local variables differently. There is no
> fundamental reason to do so.

Actually there is: instance variables belong to an object and maintain
its state, while local variables do not.  So "freezing local
variables" (i.e., making some local variable identifiers un-reusable)
really should be discussed completely separately from Kernel#freeze,
perhaps given a different name even for purposes of discussion, since
it's a basically different concept.


David

-- 
David A. Black
dblack / wobblini.net