views:

189

answers:

2

If I'm turning a ruby hash into a string of name-value pairs (to be used in HTTP params, for example), is this the best way?

# Define the hash
fields = {"a" => "foo", "b" => "bar"}

# Turn it into the name-value string
http_params = fields.map{|k,v| "#{k}=#{v}"}.join('&')

I guess my question is:

Is there an easier way to get to http_params? Granted, the above way works and is fairly straightforward, but I'm curious if there's a way to get from the hash to the string without first creating an array (the result of the map method)?

+3  A: 

This is probably the best you can do. You could iterate through the pairs in the hash, building the string as you go. But in this case the intermediate string would need to be created and deleted at each step.

Do you have a use-case where this is a performance bottleneck? In general Ruby doing so much work behind the scenes that worrying about a temporary array like this is probably not worth it. If you are concerned that it may be a problem, consider profiling your code for speed and memory usage, often the results are not what you expect.

momeara
No, I'm not worried about it being a performance issue -- I'm just still relatively new to ruby and was curious to see if there was an 'easier' way. Seems every time I start writing a method, I find a ruby or rails method that does exactly the same thing (e.g. `distance_of_time_in_words`). :)
jerhinesmith
+3  A: 

From the The Pragmatic Programmer's Guide:

Multiple parameters passed to a yield are converted to an array if the block has just one argument.

For example:

> fields = {:a => "foo", :b => "bar"}
> fields.map  { |a| a } # => [[:a, "foo"], [:b, "bar"]]

So your code could be simplified like this:

> fields.map{ |a| a.join('=') }.join('&') # => "a=foo&b=bar"
Christian
I fail to see how this is simpler. If anything, it hides the intention of the code behind the "multiple parameters => array" magic.
Ben
Well, it is certainly a matter of taste. *I* find it simpler because it constructs the string without my having to explicitly deal with keys and values.I agree it's less readable, though.
Christian