[prev in list] [next in list] [prev in thread] [next in thread] 

List:       ruby-core
Subject:    [ruby-core:70911] [Ruby trunk - Feature #11550] Current behaviour of super(...) is dangerous in the 
From:       eregontp () gmail ! com
Date:       2015-09-25 11:08:47
Message-ID: redmine.journal-54277.20150925110846.99c81def29db0657 () ruby-lang ! org
[Download RAW message or body]

Issue #11550 has been updated by Benoit Daloze.


Why not simply having `super` in M1 and M2 #initialize?
All constructors should call `super`, unless they just inherit from \
Object/BasicObject.

----------------------------------------
Feature #11550: Current behaviour of super(...) is dangerous in the presence of more \
than one included modules. https://bugs.ruby-lang.org/issues/11550#change-54277

* Author: Ronald Fischer
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
Consider a class

~~~
   class C <P
     include M1
     include M2
     def initialize
       ....
     end
   end
~~~ 

If P, M1 and M2 all provide a initialize method, and C::initialize calls super(...), \
the first initialize module in the chain, which has a formal parameter list matching \
the actual parameters in the super(....) call, is executed. The other ones are not \
executed. The following article demonstrates a clever way, how C::initialize can call \
all initializers of the included modules and of the parent class:

[[http://stdout.koraktor.de/blog/2010/10/13/ruby-calling-super-constructors-from-multiple-included-modules/]]


This solution works, but is complicated, and the reason is that the basic design of \
Ruby, with respect of initializing the base class, is flawed, for the following \
reason:

If we define an 'initialize' method, we certainly assume that its execution is \
necessary for the correct behaviour of our class or module. Therefore, the designer \
of a class or module should at least have the possibility to REQUIRE that initialize \
will be called (by a derived class), and the designer of a class which inherits from \
a parent class or includes a module, should have an EASY way to call all the parent \
initializers.

Here a first draft of how the language could be changed to meet this criterium; it's \
perhaps not the best design, but it might help clarifying my point:

(1) A class (or module) may define either a method initialize or a method \
initialize_strict (but not both). If it has initialize_strict defined, and the class \
where the module is included, respectively the class which inherits it, does NOT \
invoke this initializer, an exception is thrown, UNLESS initialize_strict can be \
called without parameters. In the latter case, it is always executed (even if no \
'super' call is present). 

(2) A class method super_of is added to class Object, with the prototype \
super_of(klass,arg*), where klass is a symbol or String or instance of type Class or \
Module. The affect of invoking super_of(:Foo,x,y) is identical to invoking \
initialize(x,y) in the ancestor class Foo. If Foo is neither a direct ancestor nor an \
included module, an exception is thrown.




-- 
https://bugs.ruby-lang.org/


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic