Re: Printing Variable Variables
by graff (Chancellor) on Sep 13, 2005 at 04:59 UTC
|
I know this is really dumb and basic but I can't figure it out.
What it is is really unnecessary. This is what arrays are for. Would you care to explain why you don't want to use an array?
#!/usr/bin/perl -w
use strict;
my @string = qw/Jessy Bob Nancy/;
my $num = 0;
while ( $num < @string ) {
print "$string[$num] ";
$num++;
}
### or, instead of a loop, just:
print "\n@string\n";
update: If the reason for not using an array is that the numeric index can be really large (meaning it can be a very sparse "array"), then this is what hashes are for -- just use the numeric as the hash key instead of as an array index. | [reply] [d/l] |
|
|
I'm trying to make a CGI script that will take two form fields and let a user enter in an unlimited amount of data points. For instance they will select a city and distance, then a second city and distance, then a third... etc..
You can see by executing my code what I'm trying to do, I just can't get the values from one submission to another to stay.
Any ideas?
#!/usr/bin/perl -w
use CGI::Carp qw(fatalsToBrowser);
use strict;
use CGI;
my $cgi = CGI->new();
my $city1 = $cgi->param("city"); # Get a fresh warning point
my $distance1 = $cgi->param("distance");
my @parameterNames = $cgi->param;
my $numCity = 0; #Counter for all the Cities passed back to the scrip
+t
foreach(@parameterNames){
if(/city/) { #Check each paramater to see if is a "city" is present
$numCity++; #If it is a city, add it to the counter
}
}
print $cgi->header;
my $action = "help.pl";
print $cgi->start_form(-action=>$action);
my $quit = '1';#Once this # gets high enough, the loop "quits"
if ($numCity){ #If there are any cities, print them as hidden fields
while($quit <= $numCity) {
# my $hiddenCity = "\$city".$quit;
# my $hiddenCityValue = eval $hiddenCity;
# my $hiddenDistance = "\$distance".$quit;
# my $hiddenDistanceValue = eval $hiddenDistance;
my $hiddenCityName = "city".$quit;
my $hiddenDistanceName = "distance".$quit;
my $hiddenCityValue = $cgi->param("$hiddenCityName");
my $hiddenDistanceValue = $cgi->param("$hiddenDistanceName");
print $cgi->hidden("$hiddenCityName", "$hiddenCityValue");
print $cgi->hidden("$hiddenDistanceName", "$hiddenDistanceValue");
print "$hiddenCityName => $hiddenCityValue<br>";
print "$hiddenDistanceName=> $hiddenDistanceValue<br><hr>";
$quit++;
}
}
print <<EOF;
<select name="city" tabindex="1">
<option value="1">Columbus</option>
<option value="2">Chicago</option>
</select>
   Distance: <input type="text" name="circularWarningD
+istanceStart" size="6" maxlength="6" />
<br>
EOF
print $cgi->submit('Go');
print $cgi->end_form;
| [reply] [d/l] |
|
|
my @cities,@distances;
if ($cgi->param('hiddenCities')) { # there are cities and distances
# from before
@cities = split(';',$cgi->param('hiddenCities'));
@distances = split(';',$cgi->param('hiddenDistances'));
}
if ($cgi->param('Go')) { # form was submitted
push @cities,$cgi->param('city');
push @distances,$cgh->param('circularWarningDistanceStart');
}
# put list of cities back on the form
print $cgi->hidden('hiddenCities',join(';',@cities);
print $cgh->hidden('hiddenDistances',join(';',@distances);
# ....
# do more form stuff here
# like asking for more input, etc.
The code above is untested, but I hope that gives you some ideas you could use.
Sean | [reply] [d/l] |
Re: Printing Variable Variables
by pg (Canon) on Sep 13, 2005 at 04:38 UTC
|
Global symbol "$string" requires explicit package name at math1.pl lin
+e 10.
Execution of math1.pl aborted due to compilation errors.
You would have found out the issue very easily by yourself, if you have warnings on.
What you want is an array, and it is a bad idea to do what you are trying to do (and I am not going down the eval path):
use strict;
use warnings;
my @strings = ("Jessy", "Bob", "Nancy");
for (@strings) {
print $_, "\n";
}
| [reply] [d/l] [select] |
A reply falls below the community's threshold of quality. You may see it by logging in. |
Re: Printing Variable Variables
by GrandFather (Saint) on Sep 13, 2005 at 04:47 UTC
|
use warnings;
use strict;
use strict;
my $string0 = "Jessy";
my $string1 = "Bob";
my $string2 = "Nancy";
my $num = 0;
while( $num != 3 ) {
print eval "\$string$num";
$num++
}
Update Note that using variable variables in this way walks around error checking that use strict provides and can lead to some pretty wierd run time behaviour. In general you should avoid the use of string eval unless you know exactly what is being evaled, and even then there are often better ways of achieving the result you need.
In this case you could:
my @strings = ("Jessy", "Bob", "Nancy");
print join "", @strings;
for example. There are many other way to do this!
Perl is Huffman encoded by design.
| [reply] [d/l] [select] |
Re: Printing Variable Variables
by sk (Curate) on Sep 13, 2005 at 04:35 UTC
|
Update: Please note that eval could be risky/dangerous. I got carried away and gave you an answer that you are looking for. However, I feel pg's and graff's solutions are much better and you should consider using that idea instead of eval. Thanks to merlyn for prompting me to explain!
You want to eval
is this what you want?
#!/usr/bin/perl -w
use strict;
my $string0 = "Jessy";
my $string1 = "Bob";
my $string2 = "Nancy";
my $num = 0;
while( $num != 3 ) {
print eval ('$string' . $num),$/;
$num++;
}
__END__
Jessy
Bob
Nancy
| [reply] [d/l] |
Re: Printing Variable Variables
by Roy Johnson (Monsignor) on Sep 13, 2005 at 14:49 UTC
|
I'm baffled as to why anyone would recommend eval for this. What you're asking for (though not what you should use) is clearly just another application of symbolic references. Of course, you're not going to get that to work without removing a stricture.
use strict;
my $string0 = "Jessy";
my $string1 = "Bob";
my $string2 = "Nancy";
for my $num (0..3) {
no strict 'refs'; # Thanks for the correction, tinita
print "${qq(string$num)}\n";
}
Common Beginner Mistakes has a good explanation of why you almost never want to use symbolic refs.
Caution: Contents may have been coded under pressure.
| [reply] [d/l] [select] |
|
|
no strict 'references';
uhm... Unknown 'strict' tag(s) 'references' at -e line 2
you meant no strict 'refs' i guess =)
| [reply] [d/l] [select] |
Re: Printing Variable Variables
by Anonymous Monk on Sep 13, 2005 at 21:34 UTC
|
| [reply] |
Re: Printing Variable Variables
by monarch (Priest) on Sep 13, 2005 at 04:48 UTC
|
Whilst not the best answer, this works: my $string0 = "Jessy";
my $string1 = "Bob";
my $string2 = "Nancy";
my $num = 0;
while( $num < 3 ) {
my $stringnum = "\$string" . $num;
my $result = eval $stringnum;
print $result . "\n";
$num++;
}
This produces the following output: Jessy
Bob
Nancy
| [reply] [d/l] [select] |
|
|
my $stringnum = "\$string" . $num;
my $result = eval $stringnum;
(Note: I gave monarch a chance to fix his own article in /msg, but he blew me off in /msg and is now ignoring me, so I have to make this a public comment instead. I think that qualifies as "trying to do the right thing first".)
Please don't use eval for this without adding a big "don't do this, though". It invokes the compiler needlessly, and it also encourages variable variables, which is a broken form of programming.
I'd elaborate, but other answers in this thread already have better solutions.
I just needed to flag monarch's solution as bad since he was unwilling to do that himself.
| [reply] [d/l] |