On Sun, May 27, 2007 at 06:25:09AM +0900, Henrik Schmidt wrote: > >(1) All objects are descendants of Object, which in turn mixes in Kernel. > >Many other objects mix in Enumerable, Comparable and other modules. > > > >This means that a typical object has roughly a googol different methods > >already present, and it's very easy to pick a local variable name which > >happens to collide with one. Silently ignoring this "just works". Giving an > >error would be very annoying; instead of "id = 9" I'd have to change it to > >"my_id = 9" or somesuch. In the end I'd prefix all local variables with > >my_... which would be worse than using something perlish like "$" > > Hmmm, I didn't think of that. Local variable/method ambiguity is only a > problem within the class. If you mix in something, you need to be aware > of which methods these mixins have. Otherwise you, or anyone who uses > your class might get unexpected results. If I decide to give all my > classes an id method, someone calling the my_class.id will probably not > get the result he wanted. I disagree. If someone uses your class, then he or she will look at your rdoc documentation, and see you have an 'id' method and, if it's what they want to use, will call it. Now of course, this hides the system 'id' method (which happens to be deprecated anyway). But you'll find this done where it's appropriate, e.g. ActiveRecord uses foo.type = bar However, this has no impact at all on local variables. If a user of your class decides to write "id = 123", then this *always* generates a local variable, and this can be seen immediately, by inspection of the code locally, without having to cross-reference to the class definition. Equally, if you do class Myclass < Other def foo ... x = 1 ... end end then you don't have to worry whether class Other has a method called 'x' or not (or if it doesn't today, that perhaps it might grow one tomorrow). It's unambiguously a local variable called 'x' that you're using. > class Point > attr_accessor :x, :y > > def initialize(init_x,init_y) > x, y = init_x, init_y > end > end > > p Point.new(10,10).x => nil > > That's a fair mistake. The compiler doesn't know about the attr_accessor > so it thinks x and y are local variables. What I don't understand is, > that even if you put in the appropriate methods instead of relying on > attr_accessor, it still doesn't work. Because of the very simple rule that says "a statement of the form 'x = ...' *always* makes x a local variable from this point until the end of the current scope". If you want to call a method called 'x=' then you always need to do self.x= I sympathise with your concern - a few times I've written some code which fails unit tests and had to stare at it for a while, before realising what I'd done. This is particularly true for ActiveRecord, which has lots of accessors, and where you might be tempted to write "something = nil" instead of "self.something = nil" However, if you want a warning for the code above, I think a better one would be "local variable x assigned but not used". Actually that shouldn't be too hard to add, and I imagine it could indeed catch a few silly typos. Regards, Brian.