> * Unless the parameters make use of "[]" in the key, it should
> function identical the current parser
> * For now, all keys will be strings. Save indifferent string/symbol
> access for another day.
> * Empty brackets signals the start of an array of keys. "foo[]=bar&foo
> []=baz" => {"foo" => ["bar", "baz"]}
#parse_query already does this (in conformance with CGI semantics):
>> Rack::Utils.parse_query("foo=1&foo=2")
=> {"foo"=>["1", "2"]}
(CGI.parse always returns Arrays, btw.)
> * A key within brackets signals the start of a hash. "foo[bar]=1&foo
> [baz]=2" => {"foo" => {"bar" => "1", "baz" => "2"}}
> * Deep levels of nesting should follow the same rules
What is foo&foo=1&foo[]=2&foo[bar]=3?
> * Rack::Multipart.parse should build on top of Utils.parse_query so it
> can take advantage of nested params as well
--
Christian Neukirchen <chneuk...@gmail.com> http://chneukirchen.org
Interesting. So we could probably strip out the empty brackets, so
"foo=1&foo=2" and "foo[]=1&foo[]=2" would have the same output.
> What is foo&foo=1&foo[]=2&foo[bar]=3?
For foo&foo=1&foo[]=2&foo, I'd would guess, { "foo" => ["", "1", "2"] }.
Not sure what to do about cases that have an array and hash: foo[]=1&foo[bar]=2
--
Joshua Peek
Tested on Rails:
TypeError: Conflicting types for parameter containers. Expected an
instance of Array but found an instance of Hash. This can be caused by
colliding Array and Hash parameters like qs[]=value&qs[key]=value.
(The parameters received were {"bar"=>"3"}.)
--
Joshua Peek
I'm inclined to treat any key with /(\[\w*\])+$/ as a hash, as arrays
can already be generated by simply repeating the key in the query
string. The only catch for me would whether to store the value at ''
or nil.
All the /\[\]$/ suffix does, as specified at this point, is generate
an explicit array. Which, reminding me of the php manner of arrays and
hashes being associative lists, does not seem to follow the pols as
well. Well, seems pols now with the general behavior being common
place.
I'm actually in favor of Rack::Utils.parse_query returning values as
hashes, where '&foo=bar' would result in {'foo'=>['bar']} akin to
CGI.parse.
--
stadik.net
It might be very beneficial if we could expand this to include at
least unicode keys/values, if not any other encoding since 1.8 has so
inferior support.
Could we spec specific failure conditions for bad data?
Learned something new. Using [] explicitly forces an array.
"foo=1" => {"foo" => "1"}
"foo=1&foo=2" => {"foo" => ["1", "2"]}
"foo[]=1" => {"foo" => ["1"]}
"foo[]=1&foo[]=2" => {"foo" => ["1", "2"]}
This is really useful for checkboxes when you always want an array of
the selected options even when the user only selects 0, 1, or more.
--
Joshua Peek
Its a gist now, so people should be able to fork it.
--
stadik.net
you'd prefer clobbering to occur?
--
stadik.net
I honestly would love to treat parsed cgi parameters as a simple data
store. If there's nothing at a key, nil. If there's one or more values
at a key (including an empty string) return an Array of the values. I
can totally deal with the additional type check of a hash on top of
that, but I _hate_ edge cases surrounding a possible single
accidentally omitted character.
--
stadik.net
> If there's one or more values
> at a key (including an empty string) return an Array of the values.
+1, the current behavior actually is a misunderstanding of me. ;-)
> Perhaps we should settle on a policy similar to: if there are any questions
> about what should be done with the data, put it in an array of values. That way
> we still get a hash-like experience but for questionable data we pack it into
> an array.
Or maybe req.params["foo"].first, but req["foo"]? That's what cgi.rb does...
Current Diff:
http://rack.lighthouseapp.com/attachments/82998/params_parser-3.diff