# Can Ruby do the Objective-C/Cocoa style alloc/init pattern?

**URL:** <https://www.ruby-forum.com/t/can-ruby-do-the-objective-c-cocoa-style-alloc-init-pattern/83211>\
**Category:** Ruby\
**Created:** [January 24, 2007, 10:51am UTC](https://www.ruby-forum.com/t/can-ruby-do-the-objective-c-cocoa-style-alloc-init-pattern/83211 "2007-01-24T10:51:08Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 24, 2007, 10:51am UTC](https://www.ruby-forum.com/t/can-ruby-do-the-objective-c-cocoa-style-alloc-init-pattern/83211/1 "2007-01-24T10:51:08Z")

</div>

In Objective-C/Cocoa objects normally come to life in the following  
way:

instance = [[Class alloc] init];

The “Class” is sent an “alloc” message (memory is allocated and a new  
instance is actually created) and then the new instance is sent an  
“init” message (allowing the object to prepare itself for use).

This pattern allows you do some cool dynamic things. For example, in  
your “init” method you can actually return a different object than the  
one that was allocated. This is pretty cool because it means you can  
return objects of different classes depending on the parameters that  
are passed to your “init” method.

Is there any way to do something similar in Ruby? Sending “new” to a  
class in Ruby is kind of like doing an “alloc” in Objective-C/Cocoa,  
and the Ruby “initialize” method is similar to the Objective-C/Cocoa  
“init” method; but unlike Objective-C/Cocoa it really doesn’t matter  
what you return from your “initialize” method so there doesn’t seem to  
be any way to return an object of a different class.

I can think of ways to fake this pattern but I am not sure if they’re  
the best idea. For example, I could add a new class method (could even  
call it “alloc” if I wanted) and a new instance method “init” and  
basically fake the Cocoa/Objective-C behaviour; but I don’t want to  
deform Ruby until it looks like Objective-C, I’d rather find a means of  
implementing this pattern the “Ruby Way”.

What do the experienced Rubyists have to say?

Cheers,  
Greg

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 24, 2007, 6:32pm UTC](https://www.ruby-forum.com/t/can-ruby-do-the-objective-c-cocoa-style-alloc-init-pattern/83211/2 "2007-01-24T18:32:56Z")

</div>

Alle 10:50, mercoledì 24 gennaio 2007, Greg H. ha scritto:

> your “init” method you can actually return a different object than the
> 
> Greg  
> I’m not an experienced rubyst, but I think you need to overload new, not  
> initialize:

class A  
def initialize  
puts “initialize for class A”  
end  
end

class B  
def initialize arg  
puts “initialize for class B. arg is #{arg}”  
end  
end

class C  
def initialize  
puts “initialize for class C”  
end  
end

class D  
def self.new cls, \*args  
const\_get(cls).new \*args  
end  
end

a=D.new ‘A’  
=\> initialize for class A  
b=D.new ‘B’, 1  
=\> initialize for class A  
c=D.new ‘C’  
=\> initialize for class A

puts a.class  
=\> A  
puts b.class  
=\> B  
puts c.class  
=\> C

At any rate, I’m not sure this is the best way, at least if class D  
should  
never be instantiated. In this case, I’d go with a module:

module Mod

class A  
end

class B  
end

class C  
end

def Mod.create cls, \*args  
const\_get(cls).new \*args  
end

end

puts Mod.create(‘A’).class  
=\>A

Stefano

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 24, 2007, 8:08pm UTC](https://www.ruby-forum.com/t/can-ruby-do-the-objective-c-cocoa-style-alloc-init-pattern/83211/3 "2007-01-24T20:08:23Z")

</div>

On Jan 24, 2007, at 01:50, Greg H. wrote:

> In Objective-C/Cocoa objects normally come to life in the following  
> way:
> 
> instance = [[Class alloc] init];
> 
> The “Class” is sent an “alloc” message (memory is allocated and a new  
> instance is actually created) and then the new instance is sent an  
> “init” message (allowing the object to prepare itself for use).

new is written like:

class Object  
def self.new(\*args, &block)  
obj = allocate  
obj.send(:initialize, \*args, &block) # initialize is private  
obj  
end  
end

–  
Eric H. - removed\_email\_address@domain.invalid - [http://blog.segment7.net](http://blog.segment7.net)

I LIT YOUR GEM ON FIRE!

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 25, 2007, 6:25pm UTC](https://www.ruby-forum.com/t/can-ruby-do-the-objective-c-cocoa-style-alloc-init-pattern/83211/4 "2007-01-25T18:25:24Z")

</div>

Thankyou to everybody who participated in this thread. I think you’ve  
covered all the bases quite nicely.

Thanks,  
Greg

---

<div class="post-metadata">

**Author:** ![greg](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/71c47a/32.png) [@greg](https://www.ruby-forum.com/u/greg)\
**Post date:** [January 24, 2007, 8:27pm UTC](https://www.ruby-forum.com/t/can-ruby-do-the-objective-c-cocoa-style-alloc-init-pattern/83211/5 "2007-01-24T20:27:26Z")

</div>

On Jan 24, 2007, at 2:07 PM, Eric H. wrote:

> ```
> obj.send(:initialize, *args, &block) # initialize is private
> obj
> 
> ```
> 
> end  
> end

A less drastic approach than overriding new in the class is to simply  
write your own specialized constructor, which can itself call new,  
allocate, or #initialize, in whatever combination is needed.

class A  
def self.my\_constructor(\*a, &b)  
# whatever but good idea to ensure that  
# an instance of A is returned.  
end  
end  
a = A.my\_constructor

I think that overriding A#new in such a way that it returns something  
other than an instance of A should be avoided. The general principle  
is that a class should be a factory for its own instances. If you want  
a more general factory pattern, I’d use a module method that delegated  
construction to an appropriate class:

class A;end  
class B;end  
module Factory  
def self.build(a)  
case a  
when ‘A’ then A.new  
when ‘B’ then B.new  
else raise ArgumentError, “‘A’ or ‘B’ expected”  
end  
end  
end

Factory.build ‘A’ # instance of A  
Factory.build ‘B’ # instance of B  
Factory.build ‘C’ # ArgumentError

Gary W.
