From: James French Date: 2012-02-22T00:17:14+09:00 Subject: Re: Difference between 1.9.2 and 1.9.3 -----Original Message----- From: Robert Klemme [mailto:shortcutter@googlemail.com] Sent: 21 February 2012 14:48 To: ruby-talk ML Subject: Re: Difference between 1.9.2 and 1.9.3 On Tue, Feb 21, 2012 at 11:44 AM, James French wrote: > > From: peter.vandenabeele.be@gmail.com > [mailto:peter.vandenabeele.be@gmail.com] On Behalf Of Peter Vandenabeele > Sent: 21 February 2012 10:01 > To: ruby-talk ML > Subject: Re: Difference between 1.9.2 and 1.9.3 > > > > On Tue, Feb 21, 2012 at 9:40 AM, Bartosz Dziewoński > wrote: > Just write `super()` when calling the higher up initializer. But do it in the child class not in the module! > Calling super() does fix this trivial example but I also happen to include > the module from a class that inherits from another class before Object, so > it breaks that. What we need to figure out is how does one write > initialize() in a module such that it seamlessly integrates into any > inheritance chain in 1.9.3. It doesn’t seem possible (at least without some > hacking) in 1.9.3. Maybe it is actually a bug somewhere. > > > > I will probably hack round it with > >   def initialize(*args, &block) >     if self.class.superclass === Object >       super() >     else >       super >     end >   end > > Is there a better way? IMHO the quoted 1.9.2 version is the buggy one because it should have raised an error in the first place. The most portable way to write a module #initialize method is to do def initialize(*a, &b) super # module init end or, if you like to be explicit def initialize(*a, &b) super(*a, &b) # module init end Because then you can insert it into *any* inheritance hierarchy. And your "hacking around" is not necessary. In cases where the superclass is Object the real culprit is the child class: that should use "super()" and not "super" because it knows its super class and knows the argument list. I think it is a bad advice to do def initialize(*a, &b) super() # always no args! # module init end This will _only_ work in cases where the super class or the module next in inheritance hierarchy does not accept arguments. Thanks for the help and input (as always Robert!), but I've got the feeling you've just restated my initial problem. Here is some more code. If you could tell me precisely what to change to make it work without hacking around (which is what I want!) then I'd be very grateful :) Notice that module A is included both by a class that doesn't inherit and by one that does. module A def initialize(*args, &block) super end end class C def initialize(name) end end class B < C include A def initialize(name) super end end class D include A def initialize(name) super end end B.new('foo') D.new('bar') -> Ruby errors