Comments at the end...

On Wed, 15 May 2002 21:21:29 +0900
"David Alan Black" <dblack / candle.superlink.net> wrote:

> Hello --
> 
> On Wed, 15 May 2002, Dossy wrote:
> 
> > On 2002.05.15, David Alan Black <dblack / candle.superlink.net> wrote:
> > > Hello --
> > >
> > > On Wed, 15 May 2002, Dossy wrote:
> > >
> > > > OR, if you only want the single value regardless:
> > > >
> > > > ... do some stuff with cgi["key"][0] ...
> > > >
> > > > However, this gets dangerous if cgi["key"] has no values and
> > > > thus returns nil, NilClass#[] isn't defined, is it.  So,
> > > > we have to guard references to cgi["key"][0] with cgi["key"].nil?
> > > > tests?  Yuck.
> > >
> > > You could define your #[] to return an empty array instead of nil
> > > for non-existent keys.
> >
> > Given the parameters:  foo=bar&quux=
> >
> > There's a big semantic difference between cgi["foo"], cgi["quux"]
> > and cgi["abc"].
> >
> > cgi["foo"].to_a         # => ["bar"]
> > cgi["quux"].to_a        # => []
> > cgi["abc"].to_a         # => nil
> 
> I was responding to the [0] point quoted above, specifically the
> concern that nil wouldn't respond to #[].

I'm getting into this discussion a bit late, but it doesn't seem like it's winding down, so I thought I'd throw in a few more suggestions, having toyed with some code over recent days.

I guess I'd like to think of the parameters being passed in the query string and in form submission as objects.  (I probably sound like a total Ruby snob saying that. ;D )  In most cases, this will be a string with metadata attached.  For example, consider looking at the parameters as properties of cgi.params:

   p cgi.params.foo
   #=> 'bar'
   p cgi.params.foo['method']
   #=> 'GET'

The metadata would definitely be more useful for multipart forms.  The idea here is to have a Hash object that defaults to return the value of its dominant key.  I think that may have even been the idea behind the 'mixing in the CGI::Params class' that was mentioned in a previous post.

In the above example, 'cgi.params.foo' would have a dominant key of (for example) 'data'.  So the following would be equivalent:

  p cgi.params.foo
  #=> 'bar'
  p cgi.params.foo['data']
  #=> 'bar'

The only conflict I've seen with this technique is when another hash is stored as the 'data' element.

  cgi.params.foo = {'greeting' => 'hello', 'farewell' => 'bye'}
  p cgi.params.foo['greeting']
  #=> NameError
  p cgi.params.foo['data']['greeting']
  #=> 'hello'

A way around this might be to allow metadata to be accessed through the accessor method:

  p cgi.params.foo( 'method' )
  #=> 'GET'
  p cgi.params.foo['greeting']
  #=> 'hello'
  p cgi.params.foo( 'data' )['greeting']
  #=> 'hello'

I know people like the cgi['foo'] notation, but it begs for a cluttering of the object namespace and limits what we can do with the params object.  If anyone's interested in seeing some proof-of-concept code, I can introduce it, but it's pretty standard stuff.

--

Jonathan Gillette
iNetZ Media
(801) 415-2566