From: "Mauricio Fernández" Date: 2003-02-02T19:34:40+09:00 Subject: Re: no override On Sun, Feb 02, 2003 at 06:41:45PM +0900, Mauricio Fern�ndez wrote: > On Sun, Feb 02, 2003 at 04:51:08PM +0900, Tom Sawyer wrote: > > is there any way to specifiy that a method can not be overrided? perfereably > > without throwing an error; rather if you try to override the method it simply > > dosen't happen. > > Kind of evil, but works: [...] Forget that code, the following is much better as now: * you can use no_redef before defining methods in the base class, only derived classes are affected * you can "stack" the restrictions, ie if you have C < B < A, you can specify that some methods of A shouldn't be overloaded, and later that some in B shouldn't be either, and it'll just work. And it gives a nice example of what class instance variables are good for :-) Drawback: method definition is somewhat slower, but _only_ definition. batsman@tux-chan:/tmp$ expand -t 2 f.rb module NoOverloading def no_redef(*args) @no_override ||= [] args.each { |i| @no_override << i } end def __no_redef_list__ supmethods = [] (ancestors - [self]).each do |i| begin supmethods += ( i.__no_redef_list__ || []) rescue NameError end end (@no_override || []) + supmethods end def inherited sub class << sub def method_added(id) return if __no_redef_list__.index(id) == nil remove_method id end end end end class A extend NoOverloading no_redef :a, :b def a; puts "A#a"; end def b; puts "A#b"; end def c; puts "A#c"; end def d; puts "A#d"; end end class B < A def a; puts "B#a"; end def b; puts "B#b"; end def c; puts "B#c"; end def d; puts "B#d"; end no_redef :c end class C < B def a; puts "C#a"; end def b; puts "C#b"; end def c; puts "C#c"; end def d; puts "C#d"; end end c = C.new c.a c.b c.c c.d batsman@tux-chan:/tmp$ ruby f.rb A#a A#b B#c C#d -- _ _ | |__ __ _| |_ ___ _ __ ___ __ _ _ __ | '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ | |_) | (_| | |_\__ \ | | | | | (_| | | | | |_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_| Running Debian GNU/Linux Sid (unstable) batsman dot geo at yahoo dot com martin@bdsi.com (no longer valid - where are you now, Martin?) -- from /usr/src/linux/drivers/cdrom/mcd.c