On Wed, 8 Dec 2004 00:40:15 +0900, Nicholas Van Weerdenburg
<vanweerd / gmail.com> wrote:
> On Tue, 7 Dec 2004 13:44:09 +0900, Austin Ziegler
> <halostatue / gmail.com> wrote:
>> On Tue, 7 Dec 2004 12:07:32 +0900, itsme213
>> <itsme213 / hotmail.com> wrote:
>>>> Eric points to variable.c, which implements the policy
>>>> annunciated by itsme. And David correctly points out that the
>>>> simple view of only looking at the instance variables does not
>>>> paint the whole picture (e.g. freezing arrays).
>>> I was talking about the pure object model part of Ruby. In such
>>> a pure object model, a[1] and a[2] are instance variables (some
>>> Smalltalk descriptions calls these 'indexed instance variables'
>>> as opposed to 'named instance variables'). How something is
>>> optimized in C is a different matter.
>> Ruby isn't Smalltalk.

>> In a Hash, foo['bar'] and foo['baz'] are not instance variables
>> of the Hash. They are indexed items to the Hash, for certain, but
>> they aren't instance variables in the least.

>> Frankly, I think your view of freezing is one that is not one
>> that is useful in considering Ruby at all.

>> I don't think that freezing bindings is at all useful, and before
>> I could even think of supporting something this drastic, I'd need
>> to see use cases that couldn't be worked around in other ways.

>>> In any case, consider my postings as a point of view; it is a
>>> clean and potentially useful one. The part about local variables
>>> was not central to me; I was just looking for a bit more
>>> uniformity in treatment of all variable bindings, even temporary
>>> (local) ones. It makes things like dynamic binding more uniform
>>> to implement.
>> I don't see any uniformity in freezing bindings.

> I think immutability is usually a good thing from a design point
> of view, so I can see a general need to have more freezing
> options.

Why? Convince me, because as someone who has done my share of design
work, I don't see immmutability as a positive on most things. On
primary key references, yes (e.g., a customer's identification
number should never change or be changed in any way), immutability
is good. But as a general rule? Immutability isn't necessarily what
you want.

(As a point of note, in my Ruby, I don't think that I've *ever* used
#freeze. In the billing design work that I did, none of it depended
upon immutability of the objects -- the only immutable things in my
code and design were *constants*.)

The "need" for immutability is very, erm, mutable and can be worked
around with various design decisions.

> When trying to extend old, bad Java code, I do some minor
> refactoring- 1. kill singletons, 2. make primary business objects
> immutable, and 3. add good logging (poor man's design-by-contract/
> testing). This makes the code understandable enough that some more
> aggressive refactoring can be done in the absense of a test suite,
> and well as enable some component level testing to be added, since
> it's now easier to seperate some of the concerns in the code (gui
> for application logic in a swing application, for instance). The
> point being the essential importance of immutability and being be
> able to control it from a contractual perspective.

You assert the value of immutability, but you haven't actually
demonstrated the value. I'm really not trying to be difficult here,
but what sort of immutability to you mean in Java -- and why do you
then need it in Ruby? I find that most of the time when people say
that they want particular features in Ruby they do so because
they're not *thinking* in Ruby, but in other languages that they
have to deal with on a daily basis to pay the bills. I know I do it,
from time to time, with C++ now that I'm making my money from that.

> And is there anyway to may attributes private so that subclasses
> can't see them? IIRC, this is possible feature of Rite. This would
> remove some of the need, since immutability is enforced by
> invisibility.

Um. What do you mean by "attributes"? If you mean that which is
generated by attr_accessor, then:

   class A
     attr_accessor :foo
     private :foo, :foo=
   end                     # => A
   class B < A; end        # => nil
   B.new.foo = :bar
      # => NoMethodError: private method `foo=' called for
      # #<B:0x2b52c38>

If you mean instance variables, no, and that wouldn't work anyway --
it would simply be a source of errors.

   class A
      attr_accessor  :foo
      private_var    :@foo
   end

   class B < A
      def foo=(x)
         @foo = x
      end
   end

Logically, this shouldn't cause a problem, because even if @foo in A
is private, then B should still be able to have it's own @foo.

Maybe there's a way around this -- and this could be potentially
very useful -- with something like:

   module A
      def foo=(x)
         @<foo> = x
      end
   end

If Ruby mangles @<foo> to be something like @__A_foo__, then you can
refer to @<foo> safely in a module without worrying about bumping
into instance variables belonging to the class.

> BTW- Is freezing bindings simply a delayed constant? Or is there
> more to it?

I don't know what itsme really wants, because I think that the idea
of making variable bindings -- instance or otherwise -- frozen is a
bad idea. Freezing an object freezes that object's state -- which
includes assignment to instance variables, certainly, but also
inclues adding singleton methods, modifying the singleton object,
extending the object, etc.

> Also, is there anything such as a deep freeze of an object graph?
> I'm guessing not, since that would something hard to generalize
> easily (I think of all the Java serializatoin performance problems
> where it turned out that the data was pulling the application
> code along with it).

No, there isn't such built into Ruby. You could write one, but I
don't think it's a good idea.

-austin
-- 
Austin Ziegler * halostatue / gmail.com
               * Alternate: austin / halostatue.ca