Note that your return
statement is problematic: The two arrays will be flattened into one and the calling code will not be able to assign the return values to two separate arrays. If you want to keep the spirit of that interface, you should return references to those arrays. See perldoc perlsub
:
A return
statement may be used to exit a subroutine, optionally specifying the returned value, which will be evaluated in the appropriate context (list, scalar, or void) depending on the context of the subroutine call. ... If you return one or more aggregates (arrays and hashes), these will be flattened together into one large indistinguishable list.
Using split
because the computer I am typing this on has neither Text::CSV
nor Text::xSV
].
#!/usr/bin/perl
use strict; use warnings;
my (@header) = map { chomp; split /,/} scalar <DATA>;
while ( my $line = <DATA> ) {
last unless $line =~ /\S/;
chomp $line;
my (@values) = split /,/, $line;
print "<select>\n";
for (my $i = 1; $i < @header; $i += 1) {
printf qq{<option name="%s" value="%s">%s = %s</option>\n},
$header[$i], $values[$i], $header[$i], $values[$i];
}
print "</select>\n";
}
__DATA__
Time,h1,h2,h3
00:00:00,n1,n2,n3
Now, if I were doing something like this, I would separate the part where I read the data and where I generate the <SELECT></SELECT>
and use a template based approach for the latter. Here is an example:
#!/usr/bin/perl
use strict; use warnings;
use HTML::Template;
use List::AllUtils qw( each_arrayref );
my $select_html = <<EO_HTML;
<select>
<TMPL_LOOP OPTIONS>
<option name="<TMPL_VAR HEADER>"
value="<TMPL_VAR VALUE>"><TMPL_VAR HEADER> = <TMPL_VAR VALUE></option>
</TMPL_LOOP>
</select>
EO_HTML
my @headers = qw(h1 h2 h3);
# Stand-in for rows you read from the CSV file
my @values = ( [qw(a1 a2 a3)], [qw(b1 b2 b3)] );
print make_select(\$select_html, \@headers, $_)->output for @values;
sub make_select {
my ($html, $headers, $values) = @_;
my $tmpl = HTML::Template->new(scalarref => $html);
my @options;
my $it = each_arrayref($headers, $values);
while ( my ($h, $v) = $it->() ) {
push @options, { HEADER => $h, VALUE => $v };
}
$tmpl->param(OPTIONS => \@options);
return $tmpl;
}
Output:
<select>
<option name="h1"
value="a1">h1 = a1</option>
<option name="h2"
value="a2">h2 = a2</option>
<option name="h3"
value="a3">h3 = a3</option>
</select>
<select>
<option name="h1"
value="b1">h1 = b1</option>
<option name="h2"
value="b2">h2 = b2</option>
<option name="h3"
value="b3">h3 = b3</option>
</select>