[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

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

Iñaki Baz Castillo

5/2/2008 10:01:00 PM

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

=2D------------------------------------
class Header
#attributes:
# - @name
# - @original_value
# - @parsed_value
# ...
end

class Message
#attributes:
# - @first_line
# - @headers =3D
# [header_1, header_2, header_3...]
# - @body
end
=2D------------------------------------

Just some headers are parsed, and for a header "From", @name attribute can =
be:
"From", "from", "FROM", "F", "f" ... =3D> /^(from|f)$/i


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

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


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

I could doing an assigment just the first time:

message.hdr_from =3D 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 m=
e=20
since I need the possibility of doing a re-assignement:

header("From") =3D header("To")

So if after doing that I use "message.hdr_from" I will access to the previo=
us=20
value of "From" header instead of the new one.


In fact, what I'm looking for is a persister pointer, concept that I alread=
y=20
know doesn't exist in Ruby :(

Thanks for any suggestion.



=2D-=20
I=C3=B1aki Baz Castillo

3 Answers

Heesob Park

5/3/2008 1:08:00 AM

0

Hi,

Iñaki Baz Castillo 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 Heesob
--
Posted via http://www.ruby-....

Iñaki Baz Castillo

5/3/2008 9:41:00 AM

0

El S=C3=A1bado, 3 de Mayo de 2008, David A. Black escribi=C3=B3:

> > So "hdr_from" is like a pointer to header("From"), but it's not valid f=
or
> > me since I need the possibility of doing a re-assignement:
> >
> > =C2=A0header("From") =3D 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 =3D 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=20
enought with parsing headers (as it would be in HTTP protocol) since I'm=20
doing a SIP stack and it can be a proxy (so some headers are modified, new=
=20
added, some deleted... and the rest of message remains equal and is forward=
ed=20
to other server.
That's why I need an efficient way of accessing the @header array of Header=
=20
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 "=3D" and use objects methods to=
=20
replace their content. Nice to know.


Thanks a lot.






=2D-=20
I=C3=B1aki Baz Castillo

Iñaki Baz Castillo

5/3/2008 12:59:00 PM

0

El S=C3=A1bado, 3 de Mayo de 2008, David A. Black escribi=C3=B3:
> You could combine these techniques, actually, if you did something
> like:
>
> =C2=A0 =C2=A0class Message
> =C2=A0 =C2=A0 =C2=A0def from_header=3D(h)
> =C2=A0 =C2=A0 =C2=A0 =C2=A0self.from_header.replace(h)
> =C2=A0 =C2=A0 =C2=A0end
> =C2=A0 =C2=A0end
>
> That's almost pseudo-code, but the point is you could then do:
>
> =C2=A0 =C2=A0message.from_header =3D message.to_header
>
> or whatever. That's the great thing about the "=3D"-methods; they let
> you use assignment semantics for method calls, and you can of course
> define the method yourself.


Great !!!

=2D-=20
I=C3=B1aki Baz Castillo