views:

276

answers:

3

I was wondering if anyone knew of a particular reason (other than purely stylistic) why the following languages these syntaxes to initiate a class?

Python:

class MyClass:
    def __init__(self):

x = MyClass()

Ruby:

class AnotherClass
    def initialize()
    end
end

x = AnotherClass.new()

I can't understand why the syntax used for the constructor and the syntax used to actually get an instance of the class are so different. Sure, I know it doesn't really make a difference but, for example, in ruby what's wrong with making the constructor "new()"?

+4  A: 

Actually in Python the constructor is __new__(), while __init__() is instance initializer.

__new__() is static class method, thus it has to be called first, as a first parameter (usually named cls or klass) it gets the class . It creates object instance, which is then passed to __init__() as first parameter (usually named self), along with all the rest of __new__'s parameters.

vartec
@SilentGhost: sorry man, it was kind of hard to edit with these in-line URLs.
vartec
+5  A: 

When you are creating an object of a class, you are doing more than just initializing it. You are allocating the memory for it, then initializing it, then returning it.

Note also that in Ruby, new() is a class method, while initialize() is an instance method. If you simply overrode new(), you would have to create the object first, then operate on that object, and return it, rather than the simpler initialize() where you can just refer to self, as the object has already been created for you by the built-in new() (or in Ruby, leave self off as it's implied).

In Objective-C, you can actually see what's going on a little more clearly (but more verbosely) because you need to do the allocation and initialization separately, since Objective-C can't pass argument lists from the allocation method to the initialization one:

[[MyClass alloc] initWithFoo: 1 bar: 2];
Brian Campbell
I'd only add that overriding new() could be useful, in, say, the case of a singleton.
Pesto
A: 

This is useful because in Python, a constructor is just another function. For example, I've done this several times:

def ClassThatShouldntBeDirectlyInstantiated():
    return _classThatShouldntBeDirectlyInstantiated()

class _classThatShouldntBeDirectlyInstantiated(object):
    ...

Of course, that's a contrived example, but you get the idea. Essentially, most people that use your class will probably think of ClassThatShouldntBeDirectlyInstantiated as your class, and there's no need to let them think otherwise. Doing things this way, all you have to do is document the factory function as the class it instantiates and not confuse anyone using the class.

In a language like C# or Java, I sometimes find it annoying to make classes like this because it can be difficult to determine whether you should use the constructor or some factory function. I'm not sure if this is also the case in Ruby though.

Jason Baker