On Aug 14, 2011, at 11:40 AM, Iñáki Baz Castillo wrote: > 2011/8/14 Chris White <cwprogram / live.com>: >> This behavior can fortunately be overridden by simply overriding the hello method in the B class, meaning that it will use the constant defined in B instead > > Yes, but it requires duplicating code. In my case I've a server class: > > > class Server > def self.foo > puts "I listen in IP #{IP}" > end > end > > > and then some classes inhereting from it: > > > class UdpServer < Server > IP = "1.2.3.4" > end > > class TcpServer < Server > IP = "1.2.3.5" > end > > > Of course "TcpServer.foo" fails: > > NameError: uninitialized constant Server::IP > I suppose the question then becomes why they have to be constants at that level. By using a module and doing a mixin (as I notice that Philip just mentioned as I'm writing this): ------------------------------------- module Server def listen(ip) # Would most likely set instance variable @ip for later use @ip = ip puts "Listening on #@ip" end end class UdpServer include Server def listen(ip) puts "UDP Listen" super end end class TcpServer include Server end TcpServer.new.listen("1.2.3.4") UdpServer.new.listen("1.2.3.5") ------------------------------------- The listen logic is centralized, and as shown in the UdpServer class, you can override the Server listen and still call its core functionality through `super`. This works out because including modules inserts into the object hierarchy as shown by doing a p TcpServer.ancestors: [TcpServer, Server, Object, Kernel, BasicObject] Regards, Chris White