# How to access to an Array element without doing "find" each time

**URL:** <https://www.ruby-forum.com/t/how-to-access-to-an-array-element-without-doing-find-each-time/136519>\
**Category:** Ruby\
**Created:** [May 3, 2008, 12:01am UTC](https://www.ruby-forum.com/t/how-to-access-to-an-array-element-without-doing-find-each-time/136519 "2008-05-03T00:01:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [May 3, 2008, 12:01am UTC](https://www.ruby-forum.com/t/how-to-access-to-an-array-element-without-doing-find-each-time/136519/1 "2008-05-03T00:01:09Z")

</div>

Hi, I’ve an Array containing complex objects of Header class:

* * *

class Header  
#attributes:

# - @name

# - @original\_value

# - @parsed\_value

# …

end

class Message  
#attributes:

# - @first\_line

# - @headers =

# [header\_1, header\_2, header\_3…]

# - @body

## end

Just some headers are parsed, and for a header “From”, @name attribute  
can be:  
“From”, “from”, “FROM”, “F”, “f” … =\> /^(from|f)$/i

Now I need to access a specifi header (“From” for example) several times  
and I  
want to avoid doing a “Header.find { |h| h.name =~ /^(from|f)$/i }” for  
each  
access,so:

class Message  
def header(name)  
Header.find { |h| h.name =~ /^(from|f)$/i }  
end  
end

But doing message.header(“From”) for each access will be not very  
efficient  
and I try to avoid it. Is there any other way?

I could doing an assigment just the first time:

message.hdr\_from = message.header(“From”)  
…do\_somethig\_with\_hdr\_from… :  
message.hdr\_from.parsed\_value.uri  
message.hdr\_from.parsed\_value.uri.name  
message.hdr\_from.parsed\_value.display\_name  
…

So “hdr\_from” is like a pointer to header(“From”), but it’s not valid  
for me  
since I need the possibility of doing a re-assignement:

header(“From”) = header(“To”)

So if after doing that I use “message.hdr\_from” I will access to the  
previous  
value of “From” header instead of the new one.

In fact, what I’m looking for is a persister pointer, concept that I  
already  
know doesn’t exist in Ruby ☹

Thanks for any suggestion.

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [May 3, 2008, 3:08am UTC](https://www.ruby-forum.com/t/how-to-access-to-an-array-element-without-doing-find-each-time/136519/2 "2008-05-03T03:08:19Z")

</div>

Hi,

IÃ±aki Baz C. wrote:

> Hi, I’ve an Array containing complex objects of Header class:
> 
> * * *
> 
> class Header  
> #attributes:
> 
> # - @name
> 
> # - @original\_value
> 
> # - @parsed\_value
> 
> # …
> 
> end
> 
> class Message  
> #attributes:
> 
> # - @first\_line
> 
> # - @headers =
> 
> # [header\_1, header\_2, header\_3…]
> 
> # - @body
> 
> ## end
> 
> Just some headers are parsed, and for a header “From”, @name attribute  
> can be:  
> “From”, “from”, “FROM”, “F”, “f” … =\> /^(from|f)$/i
> 
> Now I need to access a specifi header (“From” for example) several times  
> and I  
> want to avoid doing a “Header.find { |h| h.name =~ /^(from|f)$/i }” for  
> each  
> access,so:
> 
> class Message  
> def header(name)  
> Header.find { |h| h.name =~ /^(from|f)$/i }  
> end  
> end
> 
> But doing message.header(“From”) for each access will be not very  
> efficient  
> and I try to avoid it. Is there any other way?
> 
> I could doing an assigment just the first time:
> 
> message.hdr\_from = message.header(“From”)  
> …do\_somethig\_with\_hdr\_from… :  
> message.hdr\_from.parsed\_value.uri  
> message.hdr\_from.parsed\_value.uri.name  
> message.hdr\_from.parsed\_value.display\_name  
> …
> 
> So “hdr\_from” is like a pointer to header(“From”), but it’s not valid  
> for me  
> since I need the possibility of doing a re-assignement:
> 
> header(“From”) = header(“To”)
> 
> So if after doing that I use “message.hdr\_from” I will access to the  
> previous  
> value of “From” header instead of the new one.
> 
> In fact, what I’m looking for is a persister pointer, concept that I  
> already  
> know doesn’t exist in Ruby ☹

How about use class variable something like this:

class Message  
def initialize

```
@@header = {}

```

end  
def header(name)  
return @@header[name] ||= @headers.find { |h| h.name =~  
/^(from|f)$/i }  
end  
end

> Thanks for any suggestion.

Regards,  
Park H.

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [May 3, 2008, 3:37am UTC](https://www.ruby-forum.com/t/how-to-access-to-an-array-element-without-doing-find-each-time/136519/3 "2008-05-03T03:37:41Z")

</div>

Hi –

On Sat, 3 May 2008, IÃ±aki Baz C. wrote:

> “From”, “from”, “FROM”, “F”, “f” … =\> /^(from|f)$/i  
> end  
> message.hdr\_from.parsed\_value.uri.name  
> message.hdr\_from.parsed\_value.display\_name  
> …
> 
> So “hdr\_from” is like a pointer to header(“From”), but it’s not valid for me  
> since I need the possibility of doing a re-assignement:
> 
> header(“From”) = header(“To”)

That’s not legal Ruby. A method call isn’t an lvalue.

> So if after doing that I use “message.hdr\_from” I will access to the previous  
> value of “From” header instead of the new one.
> 
> In fact, what I’m looking for is a persister pointer, concept that I already  
> know doesn’t exist in Ruby ☹

My advice is to try to learn to think in Ruby, so that you don’t keep  
experiencing frustration because of what you perceive Ruby as not  
having. Believe me, Ruby is definitely feature-rich enough to parse  
headers 🙂

Specifically, I think you should stop thinking in terms of pointers.  
Ruby doesn’t have them, so it’s never going to be an exact fit, and it  
won’t take you very far in exploring Ruby techniques.

A lot of Ruby objects need to change their state or contents, without  
changing what object they are. Methods like Array#replace,  
String#replace, and many others, do exactly that. Maybe your message  
objects could “replace” headers with each other, or something like  
that.

David

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [May 3, 2008, 11:41am UTC](https://www.ruby-forum.com/t/how-to-access-to-an-array-element-without-doing-find-each-time/136519/4 "2008-05-03T11:41:38Z")

</div>

El SÃ¡bado, 3 de Mayo de 2008, David A. Black escribiÃ³:

> > So “hdr\_from” is like a pointer to header(“From”), but it’s not valid for  
> > me since I need the possibility of doing a re-assignement:
> > 
> > Â header(“From”) = header(“To”)
> 
> That’s not legal Ruby. A method call isn’t an lvalue.

Oh, yes, you are right!  
Please, let me know if I understand correctly why:

header(“From”) returns a value so I’m trying to do:  
value1 = value2  
that is not legal, is it?

> My advice is to try to learn to think in Ruby, so that you don’t keep  
> experiencing frustration because of what you perceive Ruby as not  
> having. Believe me, Ruby is definitely feature-rich enough to parse  
> headers 🙂

Well, in fact I’ve already done the parser (using TreeTop magic). But  
it’s not  
enought with parsing headers (as it would be in HTTP protocol) since I’m  
doing a SIP stack and it can be a proxy (so some headers are modified,  
new  
added, some deleted… and the rest of message remains equal and is  
forwarded  
to other server.  
That’s why I need an efficient way of accessing the @header array of  
Header  
objets, parse just one of them and keep the whole message as it arrived.

> A lot of Ruby objects need to change their state or contents, without  
> changing what object they are. Methods like Array#replace,  
> String#replace, and many others, do exactly that. Maybe your message  
> objects could “replace” headers with each other, or something like  
> that.

Ok, so you mean that I should avoid using “=” and use objects methods to  
replace their content. Nice to know.

Thanks a lot.

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [May 3, 2008, 2:45pm UTC](https://www.ruby-forum.com/t/how-to-access-to-an-array-element-without-doing-find-each-time/136519/5 "2008-05-03T14:45:58Z")

</div>

Hi … \<- private joke 🙂

On Sat, 3 May 2008, IÃ±aki Baz C. wrote:

> Please, let me know if I understand correctly why:
> 
> header(“From”) returns a value so I’m trying to do:  
> value1 = value2  
> that is not legal, is it?

Right; you can’t say, for example,

“a string” = 3

and every method call returns an object.

> That’s why I need an efficient way of accessing the @header array of Header  
> Ok, so you mean that I should avoid using “=” and use objects methods to  
> replace their content. Nice to know.

You could combine these techniques, actually, if you did something  
like:

class Message  
def from\_header=(h)  
self.from\_header.replace(h)  
end  
end

That’s almost pseudo-code, but the point is you could then do:

message.from\_header = message.to\_header

or whatever. That’s the great thing about the “=”-methods; they let  
you use assignment semantics for method calls, and you can of course  
define the method yourself.

David

---

<div class="post-metadata">

**Author:** ![ISSSSaki\_Baz\_C](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/51bf81/32.png) [@ISSSSaki\_Baz\_C](https://www.ruby-forum.com/u/ISSSSaki_Baz_C)\
**Post date:** [May 3, 2008, 2:59pm UTC](https://www.ruby-forum.com/t/how-to-access-to-an-array-element-without-doing-find-each-time/136519/6 "2008-05-03T14:59:30Z")

</div>

El SÃ¡bado, 3 de Mayo de 2008, David A. Black escribiÃ³:

> Â Â message.from\_header = message.to\_header
> 
> or whatever. That’s the great thing about the “=”-methods; they let  
> you use assignment semantics for method calls, and you can of course  
> define the method yourself.

Great !!!
