Building querystrings with ruby

Hi *, my question is really simple: is there a way in Ruby stdlib or in
external modules to build querystrings without creating the string from
scratch ?
For example something like:

name = "Foo Bar"
p URI::join(base_uri, query_string(name))

-> "http://foobar.org/?name=Foo+Bar"

Obviously this code is totally invented.
If not (haven't found anything in the documentation) how does people
accomplish this task ?

TIA,
  ngw

harp:~ > cat a.rb
   require "cgi"
   class Hash
     def query_string
       "?" << inject(){|a,kv| a << [CGI.escape(kv.shift), CGI.escape(kv.shift)].join("=") }.join("&")
     end
   end

   q = { "name" => "Foo Bar", "uri" => "http://ruby-lang.org" }

   p q.query_string

   harp:~ > ruby a.rb
   "?name=Foo+Bar&uri=http%3A%2F%2Fruby-lang.org"

regards.

-a

···

On Wed, 15 Mar 2006, ngw wrote:

Hi *, my question is really simple: is there a way in Ruby stdlib or in
external modules to build querystrings without creating the string from
scratch ?
For example something like:

name = "Foo Bar"
p URI::join(base_uri, query_string(name))

-> "Network Ability Ltd - Internet Systems Consultancy;

Obviously this code is totally invented.
If not (haven't found anything in the documentation) how does people
accomplish this task ?

TIA,
ngw

--
share your knowledge. it's a way to achieve immortality.
- h.h. the 14th dali lama

Now here's somewhere I can use the handy trick I learned yesterday:

"?" << inject(){ |a,(k,v)| a << [CGI.escape(k),
CGI.escape(v)].join("=") }.join("&")

But this is shorter:

"?" << inject(){ |a,kv| a << kv.map{ |e| CGI.escape(e) }.join("=") }.join("&")

And this is shorter still:

"?" << to_hash.map{ |kv| kv.map{ |e| CGI.escape(e) }.join("=") }.join("&")

Paul.

···

On 15/03/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

   require "cgi"
   class Hash
     def query_string
       "?" << inject(){|a,kv| a << [CGI.escape(kv.shift), CGI.escape(kv.shift)].join("=") }.join("&")
     end
   end

Ignore my stupidity above; this is shorter and less redundant:

"?" << map{ |kv| kv.map{ |e| CGI.escape(e) }.join("=") }.join("&")

Paul.

···

On 15/03/06, Paul Battley <pbattley@gmail.com> wrote:

And this is shorter still:

"?" << to_hash.map{ |kv| kv.map{ |e| CGI.escape(e) }.join("=") }.join("&")

-Paul Battley <pbattley@gmail.com>:

···

On 15/03/06, Paul Battley <pbattley@gmail.com> wrote:

And this is shorter still:

"?" << to_hash.map{ |kv| kv.map{ |e| CGI.escape(e) }.join("=") }.join("&")

Ignore my stupidity above; this is shorter and less redundant:

"?" << map{ |kv| kv.map{ |e| CGI.escape(e) }.join("=") }.join("&")

Wow !
Thank you both, great snippets.

  ngw

Wow, I have no idea what this does or how it works. Would you mind
taking this apart and describing how it works?

"?"<<map{|h|h.map{|e|CGI.escape(e)}*'='}*'&'

This can be spaced out a bit:

  "?" << # append what follows to the string '?'
  map { |h| # h looks like ['key', 'value'] for each key-value pair
    h.map { |e| # e looks like 'key' or 'value'
      CGI.escape(e) # escape each element
    } * '=' # join key and value with '='
  } * '&' # join each key-value pair with '&'

Is that any clearer?

Paul.

···

On 16/03/06, ebeard <ecbearden@gmail.com> wrote:

Wow, I have no idea what this does or how it works. Would you mind
taking this apart and describing how it works?

perfectly. very clever.

thanks,

chad.