From: Brian Candler Date: 2005-06-30T19:05:17+09:00 Subject: Re: yield does not take a block On Thu, Jun 30, 2005 at 01:59:27AM +0900, Eric Mahurin wrote: > --- Daniel Brockman wrote: > > Eric Mahurin writes: > > > > > I think the destructive modification of a class and of an > > object's > > > class (making its class a singleton) are the main culprits. > > > > However, I ``destructively'' modify standard library classes > > and > > modules all the time. This is a major selling point for > > Ruby. > > I'm not going to argue that it is not useful, because it is and > I use it. I'm just saying that being able to modify a class > and the (singleton) class of an object at runtime will prohibit > some amount of optimization within ruby. But a good inline cache implementation should have pretty small overhead, and is far easier than attempting to make inferences about the types of objects. Ultimately I don't see why a method call a.foo() can't be compiled into something like this: /* call a.foo() */ static int md1234; static VALUE *old_class1234; static VALUE *fn(void); if (methods_defined != md1234 || (klass = CLASS_OF(a)) != old_class1234) { fn1234 = method_find(a, "foo"); md1234 = methods_defined; old_class1234 = klass; } fn1234(); "methods_defined" is a global variable incremented every time a method is defined, to invalidate all caches. The normal case would be just a few compares before calling the cached function pointer. Anyway, there are other things in Ruby which are equally big overheads, and just as difficult to optimise out. For example, 10.times do puts "hello" end generates a new String object containing "hello" each time round the loop, which has to be garbage-collected. You can't re-use the same object unless you can be sure that no references to it have been kept anywhere else. There are both benefits and costs associated with a highly dynamic language - but given that CPUs are so cheap, and programmer time is so expensive, I think it's reasonable to go the Ruby way. Regards, Brian.