Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Ruby, what's the relationship between 'new' and 'initialize'? How to return nil while initializing?

What I want is:

obj = Foo.new(0)  # => nil or false 

This doesn't work:

class Foo   def initialize(val)     return nil if val == 0   end end 

I know in C/C++/Java/C#, we cant return a value in a constructor.

But I'm wondering whether it is possible in Ruby.

like image 720
Chris Xue Avatar asked Apr 30 '12 12:04

Chris Xue


People also ask

What does initialize method do in Ruby?

The initialize method is useful when we want to initialize some class variables at the time of object creation. The initialize method is part of the object-creation process in Ruby and it allows us to set the initial values for an object.

What is new () in Ruby?

new , the class will create a new instance of itself. It will then, internally, call the method initialize on the new object. Doing so it will simply pass all the arguments that you passed to new on to the method initialize .

What is class New in Ruby?

using Class. new declares an anonymous new class on the fly: Creates a new anonymous (unnamed) class with the given superclass (or Object if no parameter is given). You can give a class a name by assigning the class object to a constant.

How would you declare and use a constructor in Ruby?

Constructors are used to initialize the instance variables. In Ruby, the constructor has a different name, unlike other programming languages. A constructor is defined using the initialize and def keyword. It is treated as a special method in Ruby.


2 Answers

In Ruby, what's the relationship between 'new' and 'initialize'?

new typically calls initialize. The default implementation of new is something like:

class Class   def new(*args, &block)     obj = allocate      obj.initialize(*args, &block)     # actually, this is obj.send(:initialize, …) because initialize is private      obj   end end 

But you can, of course, override it to do anything you want.

How to return nil while initializing?

What I want is:

obj = Foo.new(0)  # => nil or false 

This doesn't work:

class Foo   def initialize(val)     return nil if val == 0   end end 

I know in C/C++/Java/C#, we cant return a value in a constructor.

But I'm wondering whether it is possible in Ruby.

There is no such thing as a constructor in Ruby. In Ruby, there are only methods, and they can return values.

The problem you are seeing is simply that you want to change the return value of one method but you are overriding a different method. If you want to change the return value of method bar, you should override bar, not some other method.

If you want to change the behavior of Foo::new, then you should change Foo::new:

class Foo   def self.new(val)     return nil if val.zero?     super   end end 

Note, however, that this is a really bad idea, since it violates the contract of new, which is to return a fully initialized, fully functioning instance of the class.

like image 87
Jörg W Mittag Avatar answered Oct 27 '22 02:10

Jörg W Mittag


There are important differences between the two methods.

new is a class method, which generally creates an instance of the class (this deals with the tricky stuff like allocating memory that Ruby shields you from so you don't have to get too dirty).

Then, initialize, an instance method, tells the object to set its internal state up according to the parameters requested.

Either of these can be overridden depending on what you want. For example, Foo.new might actually create and return an instance of FooSubclass if it needs to be clever enough to do that.

However, often it's better to delegate use cases like these to other class methods which are more explicit about what they do, for example Foo.relating_to(bar). Breaking other peoples expectations about what methods like new should do will confuse people more than it will help them in the long run.

As an example, look at the implementation of Singleton, a module which allows only one instance of a particular class to exist. It makes the new method private, and exposes an instance method which either returns the existing instance of the object, or calls new if it hasn't been created yet.

like image 36
Gareth Avatar answered Oct 27 '22 02:10

Gareth