Reputation: 19249
In Ruby, when making a new class, we will define the constructor method like so:
class Thing
def initialize
do_stuff
end
end
However, when actually making an instance of the object, we find ourselves not calling initialize
on the instance but new
on the class.
That being the case, why don't we instead define ::new
?
class Thing
def self.new
do_stuff
end
end
Is there something ::new
does beind the scenes that initalize
doesn't define? Are those two different at all? Would defining ::new
work? Or is it just that def initialize
is shorter (not) than def self.new
?
I'm thinking there must be a good reason for the disparity.
Upvotes: 6
Views: 527
Reputation: 27793
To provide access to instance variables.
Instance variables, such as @value
, are accessible from instances only but not from within a class method. This differs from languages such as Java where private instance variables have class rather than instance scope and are thus accessible from the static constructor.
class Thing
def initialize
@value = 42
end
end
class Thing
def self.new
# no way to set the value of @value !!!!!!!!
end
end
For those interested in the history of Ruby, the object model with instance-private instance variables goes back to Smalltalk. And you'll find the same pattern in modern Smalltalk dialect like Pharo, new
is implemented in Object
to call self initialize
such that subclasses can easily initialize instance variables.
Upvotes: 7
Reputation: 168091
allocate
as a primitive and usually define new
, then you would always have to do common things like calling allocate
and returning the object at the end, which is a redundant thing to do. By having new
and initialize
, the former will wrap the latter, so you only need to define what is wrapped, not the wrapper.new
is a class method, so when you define that, you do not have access the instance methods and instance variables by default, and you need to rely on accessors. On the other hand, initialize
is an instance method, so it will be easier to work with instance variables and instance methods.Upvotes: 4
Reputation: 15471
New allocates space for the new object and creates it. It then calls the Objects initialize method to create a new Object using the allocated memory. Usually, the only part you want to customize is the actual creation, and are happy to leave the behind memory allocation to the Object.new method, so you write an initialize method. What new is doing under the hood looks something like this (except in C):
class Object
def self.new(*args, &block)
object = allocate
object.send(:initialize, *args, &block)
return object
end
end
So when you call Object.new, what actually happens is:
1) Memory is allocated 2) The objects initialize method is called.
Upvotes: 13