From: Austin Ziegler Date: 2004-12-08T01:06:53+09:00 Subject: Re: Freezing Variable Assignment On Wed, 8 Dec 2004 00:40:15 +0900, Nicholas Van Weerdenburg wrote: > On Tue, 7 Dec 2004 13:44:09 +0900, Austin Ziegler > wrote: >> On Tue, 7 Dec 2004 12:07:32 +0900, itsme213 >> 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 # # 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) @ = x end end If Ruby mangles @ to be something like @__A_foo__, then you can refer to @ 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