From: Rick DeNatale Date: 2009-02-17T00:46:45+09:00 Subject: Re: Inherit and override in the same time? --00163630f2bfb08ba404630b16a1 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit On Mon, Feb 16, 2009 at 10:29 AM, Philippe Lang wrote: > Hi Ruby gurus, > > Let's say we have a Parent class, and a Child1 class that inherits from > the Parent class. > > I'd like to create a Child2 class that inherits most of the Child1 > class, except for one method, which I'd like to override completely. The > problem is that I need to call the method in the Parent class, and > apparently "super.super" is not supported: > > ---------------------------- > class Parent > def go > puts 'parent' > end > end > > class Child1 < Parent > def go > super > puts 'child1' > end > def a_method_id_like_to_inherit > end > end > > class Child2 < Child1 > def go > super.super > puts 'child2' > end > end > > Child2.new.go > ---------------------------- > in `go': undefined method `super' for nil:NilClass (NoMethodError) > ---------------------------- > > I ended up doing this, which apprently works. > > ---------------------------- > class Parent > def go > puts 'parent' > end > end > > class Child1 < Parent > def go > super > puts 'child1' > end > def a_method_id_like_to_inherit > end > end > > class Child2 < Child1 > def go > self.class.superclass.superclass.instance_method( :go ).bind( self > ).call > puts 'child2' > end > end > > Child2.new.go > ---------------------------- > parent > child2 > ---------------------------- > > Isn't there anything simpler than that? Or is that kind of pattern > considered as bad design maybe? > > It's not clear WHY you want to do this but.. your self.class.superclass.superclass.instance_method(:go).bind(self).call really doesn't do the same thing, in general as your desired super.super (which I've not by the way seen in other dynamic OO languages either). Consider what would happen if you added class Child3 < Child2 end Child3.new.go I think that the right way to do this is to refactor the method to extract just the behavior you want to control, so in this particular case something like class Parent def go puts 'parent' end end class Child1 < Parent def put_me puts 'child1' end def go super put_me end end class Child2 < Child1 def put_me puts 'child2' end end class Child3 < Child2 end Parent.new.go Child1.new.go Child2.new.go Child3.new.go HTH -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale --00163630f2bfb08ba404630b16a1--