# More than one initializer

**URL:** <https://www.ruby-forum.com/t/more-than-one-initializer/176231>\
**Category:** Ruby\
**Created:** [September 27, 2009, 3:07pm UTC](https://www.ruby-forum.com/t/more-than-one-initializer/176231 "2009-09-27T15:07:51Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jphastings](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ab097/32.png) [@jphastings](https://www.ruby-forum.com/u/jphastings)\
**Post date:** [September 27, 2009, 3:07pm UTC](https://www.ruby-forum.com/t/more-than-one-initializer/176231/1 "2009-09-27T15:07:51Z")

</div>

Hi all,

I have a module containing two classes the first is ‘item’ the second is  
‘search’. Lets use twitter as an example:  
module MyTwitter  
class Item  
attribute\_reader :id, :tweet  
def initialize(text)  
@tweet = text  
# Post to twitter  
@id = id\_from\_post\_operation  
end  
end

class Search  
def self.do(q)  
# perform search  
out = []  
results.each do |hit|  
# This is the problem point:  
out \<\< Item.new\_from\_data(hit.id,hit.text)  
end  
return out  
end  
end  
end

When I create a new Item object I have code that creates a new tweet  
however I’d like my Search to return an array of Item objects, but if I  
use the standard MyTwitter::Item.new I’ll be posting a new item,  
not simply creating an object with the id I have from my search.

Is there a way to create an object with a given attribute without  
calling .new?

I hope I’ve explained myself well enough! Thanks,  
JP

---

<div class="post-metadata">

**Author:** ![jphastings](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ab097/32.png) [@jphastings](https://www.ruby-forum.com/u/jphastings)\
**Post date:** [September 27, 2009, 5:06pm UTC](https://www.ruby-forum.com/t/more-than-one-initializer/176231/2 "2009-09-27T17:06:08Z")

</div>

On 27.09.2009 15:07, Jp Hastings-spital wrote:

> ```
> @id = id_from_post_operation
> end
> 
> ```
> 
> Is there a way to create an object with a given attribute without  
> calling .new?
> 
> I hope I’ve explained myself well enough! Thanks,  
> JP

You could do:

class Item  
def self.new\_from\_data(id, text)  
it = allocate  
it.id = id  
it.text = text  
it  
end  
end

Or change your initialize logic to handle both cases.

Cheers

robert

---

<div class="post-metadata">

**Author:** ![jphastings](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ab097/32.png) [@jphastings](https://www.ruby-forum.com/u/jphastings)\
**Post date:** [September 27, 2009, 5:17pm UTC](https://www.ruby-forum.com/t/more-than-one-initializer/176231/3 "2009-09-27T17:17:51Z")

</div>

Hi

> ```
> @id = id_from_post_operation
> end
> 
> ```
> 
> Is there a way to create an object with a given attribute without  
> calling .new?

You’re probably better off by not making Item.new post a tweet. Instead,  
have your initialize method only create an object with id/text  
attributes set if they are passed in. Then, create a self.post method to  
actually post tweets. It could look like this:

class Item  
attribute\_reader :id, :tweet  
def initialize(id, text)  
@id, @tweet = id, text  
end  
def self.post(text)

# Post to twitter

self.new(id\_from\_post\_operation, text)  
end

That’ll solve it I hope. By the way, if your items are tweets, it makes  
more sense to call the class Tweet rather than Item. And then the @tweet  
attribute could be @text, to make it clear as to what it is. the Search  
class probably should just be incorporated into the Tweet class, rather  
than in a separate class, unless you’re using search across a number of  
things and not just tweets. But if your items aren’t tweets, well I’m  
just being silly 🙂

---

<div class="post-metadata">

**Author:** ![jphastings](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/3ab097/32.png) [@jphastings](https://www.ruby-forum.com/u/jphastings)\
**Post date:** [September 27, 2009, 6:04pm UTC](https://www.ruby-forum.com/t/more-than-one-initializer/176231/4 "2009-09-27T18:04:30Z")

</div>

Cheers Ehsanul, yeah, they’re not tweets - just an easy way to make the  
situation understood! But thanks for your help!

Robert - thanks for the ‘allocate’ tip, that will probably be the way  
forward here. However ‘id’ and ‘tweet’ are read-only attributes (and I’d  
like them to remain that way):

NoMethodError: undefined method `id=’ for #MyTwitter::Item:0x1019bad50

I think I might play with altering the logic inside .new to  
transparently accept id/text as well, seems like the simplest way  
forward.

Cheers!  
JP
