Sun 2009-04-12 ( En pr )

One of the best articles I’ve read about general programming language topics is Jonathan Amsterdam’s Java’s new Considered Harmful (click on “Print” for a less ad-cluttered version.) He criticizes the use of the new Constructor(...) statement in Java on a functional level, concluding that “…for statically typed languages, it may not be possible to do better…”.

If you are interested in the never-ending discussion about static versus dynamic typing, I encourage you to read it. If you’re not, well, do something else.

Amsterdam also mentions Ruby’s approach to object creation, stating that it fixes a problematic behaviour of Smalltalk. Still, according to him, one problem remains:

A second drawback with […] Ruby is that initialize, being an ordinary method, does not chain: You must remember to begin your initialize methods with a call to the superclass’s initialize method.

That is true; I indeed remember having forgotten it, resulting in wild debugging. Typically, when you inherit from core classes like String or Hash, there’s nothing to initialize (actually, for most core classes it suffices to call allocate instead of new, bypassing initialize.) When you inherit from your own classes, you are likely to remember to call super when overriding initialize. But when you inherit from somebody else’s class – say ActiveRecord::Base, and you’re not DHH – you run into problems.

A {background: silver; padding: 0em 0.2em}warning: initialize method does not call super! would be annoying, since a lot of good code would raise it. Disallowing the redefinition of initialize in favor of a after_initialize hook method:

class Foo
  def initialize
  def self.method_added meth
    if meth == :initialize
      raise TypeError, 'Please override after_initialize instead of initialize.'
  def after_initialize; end

would only solve the problem for direct subclasses.

Anybody got a better idea?

Say something! / Sag was!

No markup, just plain monospace text. / Kein Markup, nur Normschrift-Klartext.