Brian Candler wrote:
If a language stops you from doing something just because it's bad
practice, then the language is treating you like an idiot.
Fine, so don't stop be. Warn me that I'm doing something which is probably a programmer error 99% of the time. Ruby stops me from all sorts of things I can do in Perl. I think that's a good thing, since I'm a horrible Perl programmer
What if I
wanted to override a function for a little while? I could assign it a
new value and use the same methods of a different class!
Then you'll just override it. My question is, why would you want to override a method with a variable? I have no problem with overloading a method with another method, and neither should the interpreter.
The trouble is:
(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. My point is, that you need to be aware that you're actually overloading a mixed in or inherited method anyway. Normally I would think that's a reasonable requirement, and anyone can look through Kernel and Object to get an idea of which method-names are dangerous. Of course, it might have been a good idea to give these methods less generic names. I'm not sure why they deprecated the id method, but I guess it might have something to do with this. Can anyone clue me in?
Anyway, it could be partially solved by only issuing a warning if your local variable is actually shadowing a local method, but I definitely see your point.
(2) From a very practical perspective, it's extremely difficult for Ruby to
generate these warnings.
The problem is: Ruby is a completely dynamic language, and at parse time you
have no idea what methods an object has. The decision as to 'local variable'
or 'method' is made statically, based on inspection of the code
*before* it's executed, which means before any classes and methods have been
created.
To perform the check you're asking for, Ruby would have to add extra
run-time code after *every* local variable access to perform a method search
just to check if a method with the same name exists. Example:
10000.times do
x = flurble()
y = y + x
end
Each time round the loop, the call to flurble() may have ended up defining a
method called 'x' in the current object. So every time round the loop, you'd
have to check, at the point where 'x' was read and/or assigned, that there
was currently no method called 'x' (or 'x=') in the object.
I found this googling (http://talklikeaduck.denhaven2.com/xml/rss20/article/256/feed.xml\):
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.
Anyway, I still think one could make a sensible warning system to be run at compile-time that would catch most of the more obvious programmer errors, but it wouldn't be perfect. The counter-argument would be that we're probably better off leaving it alone so people will fall into the trap, learn what happens, and stop doing it early on. Then again, a warning would probably lead them to the path of enlightenment earlier.
I still wouldn't mind getting a warning, but I didn't realize all the implications of trying to fix it, so I guess I can accept that since there seem to be no way to fix it properly without sigils anyway, it should be left as it is.
Thanks for the explanation,
Henrik Schmidt
···
On Sun, May 27, 2007 at 01:00:03AM +0900, Henrik Schmidt wrote:
Hakusa@gmail.com wrote: