Getting CGI arguments as scalars


(Philip Mak) #1

cgi = CGI.new
year = cgi[‘year’] => [‘2002’]

In the CGI module, all the arguments are given as arrays instead of
scalars (presumably to support the case where the HTML page had
multiple tags of the same name).

How can I get it as a scalar, though? Right now I’m using:

year ,= cgi[‘year’]

Is this a safe syntax to use (i.e. will it be valid in future versions
of Ruby)? It seems to be an abuse of the comma notation (I would think
that the comma is meant to separate lvalues).


(David Alan Black) #2

Hello –

cgi = CGI.new
year = cgi[‘year’] => [‘2002’]

In the CGI module, all the arguments are given as arrays instead of
scalars (presumably to support the case where the HTML page had
multiple tags of the same name).

How can I get it as a scalar, though? Right now I’m using:

year ,= cgi[‘year’]

Interesting – I don’t think I’ve ever seen it written with the comma
up against the = :slight_smile: (as opposed to: year, = cgi[‘year’])

You can also do:

year = cgi[‘year’][0]

By the way, there was a long thread in May about this, specifically
about the relative merits of different (from the current, and from
each other) syntax possibilities for this. (Search for “cgi params
api” on http://www.ruby-talk.org.)

Is this a safe syntax to use (i.e. will it be valid in future versions
of Ruby)? It seems to be an abuse of the comma notation (I would think
that the comma is meant to separate lvalues).

It makes sense in the context of some more examples:

a,b,c = 1,2,3 # a == 1, b == 2, c == 3
a,b = 1,2,3 # a == 1, b == 2, 3 discarded
a, = 1,2,3 # a == 1, 2 and 3 discarded
a = 1,2,3 # a == [1,2,3]
a,*b = 1,2,3 # a == 1, b == [2,3]

So the “a, =” notation (third example) is a sort of reduced or
boundary case of “a,b,c,… =”

David

···

On Tue, 2 Jul 2002, Philip Mak wrote:


David Alan Black
home: dblack@candle.superlink.net
work: blackdav@shu.edu
Web: http://pirate.shu.edu/~blackdav


(Tom Sawyer) #3

you can also modify the CGI class to return a scalar if the parameters
array only contains a sinlge element:

require ‘cgi’

class CGI
module QueryExtension
def
if @params[*args]
case @params[*args].length
when 0
return nil
when 1
return @params[*args][0]
else
return @params[*args]
end
else
return nil
end
end
end
end

as to the relative merits of this, which is better? i don’t know. but
this works well for me. the only trick is to remember to access the
paramaters (i.e.cgi.params) directly if you want to manipulate the
parameters array, as [] will no longer be certain to return such a
reference.

~transami

···

On Mon, 2002-07-01 at 14:29, Philip Mak wrote:

cgi = CGI.new
year = cgi[‘year’] => [‘2002’]

In the CGI module, all the arguments are given as arrays instead of
scalars (presumably to support the case where the HTML page had
multiple tags of the same name).

How can I get it as a scalar, though? Right now I’m using:

year ,= cgi[‘year’]

Is this a safe syntax to use (i.e. will it be valid in future versions
of Ruby)? It seems to be an abuse of the comma notation (I would think
that the comma is meant to separate lvalues).


(Dan Debertin) #4

Tom Sawyer writes:

the only trick is to remember to access the paramaters
(i.e.cgi.params) directly if you want to manipulate the parameters
array, as [] will no longer be certain to return such a reference.

Chances are you’re going to know in advance if your form (or whatever)
contains duplicate values. In these cases, why not be consistent and
convert? [] returning a different kind of object under certain
circumstances seems undesirable to me – eventually I’m going to
forget to invoke .kind_of? on the result.

Here’s what I ended up doing to solve the same problem:

module CGIFeatures

Extensions to CGI to make it act more like a hash.

def to_h
h = {}
# Obviously, this breaks duplicate CGI params.
self.keys.each { |k| h[k] = self[k][0] }
h
end
end

cgi = CGI.new
cgi.extend(CGIFeatures)
params_as_hash = cgi.to_h

Dan

···


airboss@nodewarrior.org
www.nodewarrior.org
ignorami: n:
The art of folding problem users into representational shapes.


(Tom Sawyer) #5

well, it dosen’t really end up working that way. i never use kind_of? or
the like, because, like you said, i know what my cgi form contains. thus
i know whether to expect a scalar or array before hand from a given
parameter. but i can see how this might not always be the case. but one
way or the other you going to have to deal with the possibility of
multiple array elements. your example is fine if the page dosen’t use
any duplicate input tags, as it deals with mutiple array elements by
eliimnating them --a subset of the cgi. but i often have duplicate input
tags, so it won’t work for me.

besides perhaps just leaving it as it is and grabbing the [0] index when
you know you have a scalar, i think my suggestion is the best
alternative. i’ve thought about it a long time and have not been able to
think of a better solution.

~transami

···

On Tue, 2002-07-02 at 19:04, Dan Debertin wrote:

Tom Sawyer writes:

the only trick is to remember to access the paramaters
(i.e.cgi.params) directly if you want to manipulate the parameters
array, as [] will no longer be certain to return such a reference.

Chances are you’re going to know in advance if your form (or whatever)
contains duplicate values. In these cases, why not be consistent and
convert? [] returning a different kind of object under certain
circumstances seems undesirable to me – eventually I’m going to
forget to invoke .kind_of? on the result.

Here’s what I ended up doing to solve the same problem:

module CGIFeatures

Extensions to CGI to make it act more like a hash.

def to_h
h = {}
# Obviously, this breaks duplicate CGI params.
self.keys.each { |k| h[k] = self[k][0] }
h
end
end

cgi = CGI.new
cgi.extend(CGIFeatures)
params_as_hash = cgi.to_h

Dan

airboss@nodewarrior.org
www.nodewarrior.org
ignorami: n:
The art of folding problem users into representational shapes.