Creating hash from ENV['QUERY_STRING']

Howdy - my first ever question, probably reflects my complete beginners
knowledge of the language, so here goes my best attempt to explain.

I’m trying to find a way to take the query string of the URI and create
a hash with the key/value pairs. I’m able to mostly do this but with
the caveat of each key value in the hash, being surrounded by “[”"]",
so when I try to reference the value , I can’t just put “value”, it has
to be “[“value”]”. If this is just ‘how it is’ for the method I’m
using, I’d appreciate some feedback on the best way to strip off those
extra characters if possible. Here’s what I have:

url = ENV[‘QUERY_STRING’] # process.rb?type=sms&To=1&From=2
url_hash = CGI.parse(url)
url_hash.each { | key, value | eval “@#{key} = ‘#{value}’” }
p @type

The output for the above is “[“sms”]”

How about:
querystr = ENV[‘QUERY_STRING’].split(’?’)[1]
querystr.split(’&’).map { |pair| pair.split(’=’) }.to_h

If to_h isn’t available because you’re running an older version of Ruby,
Hash[querystr.split(’&’).map { |pair| pair.split(’=’) }] should work.

Thanks.

Rpag … wrote in post #1167047:

How about:
querystr = ENV[‘QUERY_STRING’].split(’?’)[1]
querystr.split(’&’).map { |pair| pair.split(’=’) }.to_h

If to_h isn’t available because you’re running an older version of Ruby,
Hash[querystr.split(’&’).map { |pair| pair.split(’=’) }] should work.

Thanks.

Thanks so much - I’m running 1.9.3 and it didn’t like ‘to_h’ but the 2nd
executed just fine. I’m a bit confused as to how I now reference each
value now though? I took a stab at assuming it was something like:

puts hash[“type”]

but that just gave me an error “can’t convert string into integer”.
I’mm really grateful for you taking the time to answer such basic
questions!

Sure, the full code is below but it’s essentially the same code you
posted.

require ‘net/http’
require ‘cgi’

querystr = “type=sms&To=1&From=2”
Hash[querystr.split(’&’).map { |pair| pair.split(’=’) }]
puts hash[“type”]

I also tried just those last 3 lines in IRB and also get the same “can’t
convert string to integer” error when attempting to execute that last
line.

Oh I see.
You forgot to assign the second to a variable.
Kernel#hash returns an integer.
Try:
querystr = “type=sms&To=1&From=2”
hash = Hash[querystr.split(’&’).map { |pair| pair.split(’=’) }]
puts hash[‘type’]

Mike Be wrote in post #1167058:

require ‘net/http’
require ‘cgi’

querystr = “type=sms&To=1&From=2”
Hash[querystr.split(’&’).map { |pair| pair.split(’=’) }]
puts hash[“type”]

Why are you requiring “cgi” if you do not use it?

irb(main):001:0> require ‘cgi’
=> true
irb(main):002:0> querystr = “type=sms&To=1&From=2”
=> “type=sms&To=1&From=2”
irb(main):003:0> params = CGI.parse querystr
=> {“type”=>[“sms”], “To”=>[“1”], “From”=>[“2”]}

Use the right tool for the job. :slight_smile:

Cheers

robert

That error would suggest ‘hash’ is an Array and not a Hash. Can you
paste your code?

Rpag … wrote in post #1167080:

Oh I see.
You forgot to assign the second to a variable.
Kernel#hash returns an integer.
Try:
querystr = “type=sms&To=1&From=2”
hash = Hash[querystr.split(’&’).map { |pair| pair.split(’=’) }]
puts hash[‘type’]

That worked - thanks so much for your help!

Robert K. wrote in post #1167097:

Mike Be wrote in post #1167058:

require ‘net/http’
require ‘cgi’

querystr = “type=sms&To=1&From=2”
Hash[querystr.split(’&’).map { |pair| pair.split(’=’) }]
puts hash[“type”]

Why are you requiring “cgi” if you do not use it?

irb(main):001:0> require ‘cgi’
=> true
irb(main):002:0> querystr = “type=sms&To=1&From=2”
=> “type=sms&To=1&From=2”
irb(main):003:0> params = CGI.parse querystr
=> {“type”=>[“sms”], “To”=>[“1”], “From”=>[“2”]}

Use the right tool for the job. :slight_smile:

Cheers

robert

Thanks for the response Robert. The require was in there from the
original way I was attempting to do things, so it was a case of I just
hadn’t bothered taking it out yet.

As far as ‘the right tool for the job’, do you mean stick with CGI?
The code you’ve pasted gives me the same problem I started with, which
is the value of the key being displayed as “[“sms”]” so I still don’t
understand why it does that. Anyway, the non-cgi solution provided by
Rpag works perfectly.

Mike Be wrote in post #1167103:

As far as ‘the right tool for the job’, do you mean stick with CGI?

Yes, of course.

The code you’ve pasted gives me the same problem I started with, which
is the value of the key being displayed as “[“sms”]” so I still don’t
understand why it does that.

It is an Array.

Anyway, the non-cgi solution provided by
Rpag works perfectly.

I would not use it. Why reinvent the wheel when someone else has taken
the time to write the code, think of all the edge cases and tested it -
presumably more thoroughly than your non CGI solution?

It is an Array.

But as the title and post indicate, I’m trying to get a hash, so don’t
understand how your solution helps, other than telling me that I should
use CGI (and I’ve had equal people giving an opinion on various Ruby
forums, as to why I should and shouldn’t use CGI).

I’m literally using a few lines of code in a non-production environment
so Rpag’s non-CGI solution works just fine. Thanks for trying to help
though, bob.

Mike Be wrote in post #1167138:

It is an Array.

But as the title and post indicate, I’m trying to get a hash, so don’t
understand how your solution helps,

You do get a Hash. Please look at the result in
https://www.ruby-forum.com/topic/6872989?reply_to=1167138#1167097
Values are Arrays. And the reason for that lies in the nature of HTML
forms.

Cheers

robert