[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Constructing a Hash from a String?

skhisma

5/12/2006 5:44:00 PM

So I'm looking to create a Hash from a string which is pretty much
formatted like you would create a hash:

theString = "foo=>1,bar=>2,baz=>'go fish'"

and i was wondering if anyone had any nice and simple ideas for how to
grab this out. I came up with a little way to do it but i was just
wondering if anyone out there can think of a shorter way.

Here's what i came up with:

login = Hash.new
theString.split(',').each {|pair| pair.match(/(.+)=>(.+)/);
login[$1.intern]=$2 }

4 Answers

mojombo

5/12/2006 6:16:00 PM

0

Geoff wrote:
> So I'm looking to create a Hash from a string which is pretty much
> formatted like you would create a hash:
>
> theString = "foo=>1,bar=>2,baz=>'go fish'"
>
> and i was wondering if anyone had any nice and simple ideas for how to
> grab this out. I came up with a little way to do it but i was just
> wondering if anyone out there can think of a shorter way.

This is a bit obfuscational, but it works:

login = eval('{' + theString.split(',').map{|m| ':' + m}.join(',') +
'}')

Tom

Ross Bamford

5/12/2006 7:13:00 PM

0

On Fri, 12 May 2006 18:43:45 +0100, Geoff <skhisma@gmail.com> wrote:

> So I'm looking to create a Hash from a string which is pretty much
> formatted like you would create a hash:
>
> theString = "foo=>1,bar=>2,baz=>'go fish'"
>
> and i was wondering if anyone had any nice and simple ideas for how to
> grab this out. I came up with a little way to do it but i was just
> wondering if anyone out there can think of a shorter way.
>
> Here's what i came up with:
>
> login = Hash.new
> theString.split(',').each {|pair| pair.match(/(.+)=>(.+)/);
> login[$1.intern]=$2 }
>

Depends on exactly how you want the Hash, but maybe you could do:

h = Hash[*the_string.split(',').map { |e| e.split('=>') }.flatten]
# => {"baz"=>"'go fish'", "foo"=>"1", "bar"=>"2"}

or:

h = Hash[*the_string.split(',').map do |e|
e.split('=>').inject { |k,v| [k.intern,eval(v)] }
end.flatten]
# => {:foo=>1, :bar=>2, :baz=>"go fish"}

Unfortunately, if you want the second style I think you're stuck with eval
and it's (deserved) reputation as slow and insecure.

--
Ross Bamford - rosco@roscopeco.remove.co.uk

rcoder@gmail.com

5/12/2006 9:59:00 PM

0

I'd recommend staying away from using the Ruby hash syntax, unless you
also want to implement a parser for Ruby strings -- your simple version
will break if any values in your hash include a comma. For example:

theString = "foo=>1,bar=>2,baz=>'go fish, then go home'"

Your split will find the comma in the value associated with baz, but
the search for '=>' will fail, resulting in a truncated value for the
baz key.

Have you considered using YAML, or another non-Ruby syntax for the
hashes?

skhisma

5/15/2006 2:15:00 PM

0

YAML could be an option. I'll look in to it.

Thanks for the suggestions.