From: Eric Mahurin Date: 2005-08-20T04:32:24+09:00 Subject: Re: Non-overridable and non-redefinable methods --- Eric Hodel wrote: > On 19 Aug 2005, at 10:03, Eric Mahurin wrote: > > Another thing that hinders performance optimizations is the > > lack of the ability to say that a method is not overridable > in > > any derived classes. This mostly applies to many methods > in > > Object and Kernel (because everything gets those methods), > but > > could apply elswhere if the VM/compiler couldn't determine > the > > exact class but possibly the kind_of. Here are methods in > > Object that would be advantageous to inline (and not allow > to > > be overridden) for performance: > > > > __id__ __send__ class equal? extend freeze > frozen? > > id instance_eval instance_of? instance_variable_get > > instance_variable_set instance_variables is_a? > kind_of? > > method methods nil? object_id private_methods > > protected_methods public_methods > remove_instance_variable > > respond_to? send singleton_method_added > > singleton_method_removed singleton_method_undefined > > singleton_methods taint tainted? untaint > > I either never call these methods, or would use them for > making proxy > objects. > > send can be quite useful to override, and respond_to? pairs > with > method_missing, so it can't be in the list. id is used > extensively > by Rails, and is deprecated anyhow. > > I don't see why remove_instance_variable is on the list. I > may *not* > want to remove certain instance variables. I'm not saying all of these should be on the list to be non-overridable/removable. But, anything you put in this list could offer a performance advantage in some future ruby VM/compiler. The ones I think are most important are: __id__ (and maybe object_id) __send__ (and maybe send) equal? nil? Some of these even say in the docs that they shouldn't be overridden. And I think when you override __send__, it gives a warning. I'm proposing an enforcement to this. This is sort-of like "final" in java. Or not "virtual" in C++. It seems kind of silly that all of the above has to go through the method call overhead when the in-lining what these do is so trivial. > Also, we couldn't make dead-simple proxies like this: > > class BlankSlate > instance_methods.each { |m| undef_method m unless m =~ > /^__/ } > end > > class Proxy < BlankSlate > > def initialize(obj) > @obj = obj > end > > def method_missing(sym, *args, &block) > @obj.__send__(sym, *args, &block) > end > > end > > class Foo > def x; y; end > protected > def y; @y = :stuff; end > end > > foo = Foo.new > dfoo = Proxy.new foo > > p foo.protected_methods > p dfoo.protected_methods > > p dfoo.send :x > p dfoo.instance_variables You couldn't do this - unless the only non-overridable/removable methods were __send__ and __id__ - because the above code didn't want to mess with them. This is a performance vs. flexibility tradeoff. You'd want to find the right list of non-overridable/removable methods to give the best balance. __________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com