Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi,I have a form with lots of fields with same field names.

I know that I can retrieve each type of fields by storing it into an array like this:
my @fields = $INPUT->param('titles'); foreach my $f (@fields) { #do something with $f... }
However, is there anyway I can access the values differently? For example, I tried using this syntax but it produced an error:
my $title = $INPUT->param("titles")[5];
I also tried this:
my $title = @{$INPUT->param("titles")}[5];


Both returned errors and I'm not sure where to look for a right way. Is it possible? Or is the only way is to store it inside an array?

I also DO NOT want to carry out this method by this way either:
my @fields = $INPUT->param('titles'); my $title = $fields[5];


Thanks,
Sylar

Replies are listed 'Best First'.
Re: CGI.pm - multiple values for same field name
by ikegami (Patriarch) on May 25, 2007 at 03:43 UTC

    $INPUT->param("titles")
    returns a list. You can't index a list, but you can slice it.
    ($INPUT->param("titles"))[5]
    c.f. perldata

    @{$INPUT->param("titles")}[5]
    and
    $INPUT->param("titles")->[5]
    don't work because param doesn't return a reference to an array.

    $INPUT->param("titles")[5]
    it just plain invalid syntax.

      Nit -
      $INPUT->param("titles")
      returns a list. You can't index a list, but you can slice it.
      ($INPUT->param("titles"))[5]

      Sure you can - perldata uses subscript instead of index:

      A common way to access an array or a hash is one scalar element at a time. You can also subscript a list to get a single element from it.

      You can't subscript a function call, though, only its results - that's why the expression must go in parens. But you are right in that you can also slice a list :-)

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

        A common way to access an array or a hash is one scalar element at a time. You can also subscript a list to get a single element from it.

        And by doing so, you get a list slice. A single-index slice is still a slice. The difference between a slice and indexing is the context in which the index expression is evaluated.

        my @indexes = (3); my @array = (0,1,2,3,4); print($array[@indexes], "\n"); # 1 => index print(@array[@indexes], "\n"); # 3 => slice print((0,1,2,3,4,5)[@indexes], "\n"); # 3 => slice

        There's no native syntax to index a list.

Re: CGI.pm - multiple values for same field name
by shmem (Chancellor) on May 25, 2007 at 05:59 UTC
    I also tried this:
    my $title = @{$INPUT->param("titles")}[5];

    Close. You have to make the list returned by $INPUT->param("titles") into an anonymous array to dereference it proper as an anonymous array with @{ }:

    my $title = @{[$INPUT->param("titles")]}[5];

    update: answering naikonta's comment below - I would subscript the list and posted this only as an explanation of why the OP's code didn't work :-)

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      True, but why would you do that? :-)

      Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

Re: CGI.pm - multiple values for same field name
by Anonymous Monk on May 25, 2007 at 03:59 UTC
    Hi,

    Thanks! it worked!

    I will review more about slicing and accessing elements from a list. I was not familiar enough with the terms, so it was hard researching fro an answer.

    Anyhow, the only reason I wanted to access the list this way was because theres about 10 fields with the same field names and all fields are optional.
      The differences between slicing and indexing are very minor.
      Array Indexing -------------- SCALAR = $array[SCALAR EXPR]; $value = $array[5]; Array Slicing ------------- LIST = @array[LIST EXPR]; @values = @array[5,6,7]; $value = @array[5,6,7]; # Prev same as: $value = $array[7]; Hash Indexing ------------- SCALAR = $hash{SCALAR EXPR}; $value = $hash{'apple'}; Hash Slicing ------------ LIST = @hash{LIST EXPR}; @values = @hash{'apple', 'orange'}; $value = @hash{'apple', 'orange'}; # Prev same as: $value = $hash{'orange'}; List Slicing ------------ LIST = (LIST)[LIST EXPR]; @values = (split(/,/, 'a,b,c,d'))[1,2]; $value = (split(/,/, 'a,b,c,d'))[1,2]; # Prev same as: $value = (split(/,/, 'a,b,c,d'))[2];
      Anyhow, the only reason I wanted to access the list this way was because theres about 10 fields with the same field names and all fields are optional.
      But, why are you interested only in a specific value of the fields? If one has some fields with the same name, usually those field are:
      • Radio button, this allows user to select an option and only the value of the selected option will be sent to the server. In this case, $INPUT->param('fieldname') will return exactly one value.
      • Checkbox, this allows user to select more than one options and the values of selected options will be sent to the server. In this case, $INPUT->param('fieldname') will return more than one values.
      (Another case where $INPUT->param('fieldname') will return multiple values if the field type is select and multiple is true).

      So, if you know that you will get more than one values, why you're only interested in the particular value (from your example, the sixth element of the array)? If it wasn't a multiple <select> or <input type="checkbox"> field, say, a number of textfields with the same name, than there might be something wrong with your form design.


      Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!