Re: Where is my foreach data going to?
by Enlil (Parson) on Sep 18, 2003 at 01:09 UTC
|
use warnings;
near the top of your script. When I do something similiar (with warnings on)perl -MData::Dumper -we "$array[2,2] = 'foo'; print Dumper \@array"
I get the warning:
Multidimensional syntax $array[2,2] not supported at -e line 1.
Useless use of a constant in void context at -e line 1.
$VAR1 = [
undef,
undef,
'foo'
];
I have a feeling the syntax you want is more like:$athlete[$i][$j++] = $bug;
-enlil | [reply] [d/l] [select] |
|
|
Well, if I change the algorithm to :
$qry = $DB->Query("SELECT * FROM recipes WHERE type = '$type' ORDER
+BY rand()
limit $quantity") || die "Got error on select: $Mysql::db_errstr\n";
+
for ($i=0; $i<$qry->numrows; $i++) {
@row = $qry->fetchrow or warn "recipes didn't find a matching row"
+;
print "\@row is assigned @row\n";
$j = 0;
foreach my $bug (@row) {
$athlete[$i][$j++] = $bug ;
print "\$i\$j is assigned $i:$j\n";
print "\$athlete[\$i,\$j] is assigned the value $athlete[$i][$j]
+\n";
print "\$bug is assigned the value $bug\n";
}
}
}
then it yields:
@row is assigned 33 Small Bunch Grapes carb 15 0.4 0.1
$i$j is assigned 4:1
Use of uninitialized value in concatenation (.) or string at ./getCurr
+entNeeds.pl line 74.
$athlete[$i,$j] is assigned the value
$bug is assigned the value 33
$i$j is assigned 4:2
Use of uninitialized value in concatenation (.) or string at ./getCurr
+entNeeds.pl line 74.
$athlete[$i,$j] is assigned the value
$bug is assigned the value Small Bunch Grapes
$i$j is assigned 4:3
Use of uninitialized value in concatenation (.) or string at ./getCurr
+entNeeds.pl line 74.
$athlete[$i,$j] is assigned the value
$bug is assigned the value carb
$i$j is assigned 4:4
Use of uninitialized value in concatenation (.) or string at ./getCurr
+entNeeds.pl line 74.
$athlete[$i,$j] is assigned the value
$bug is assigned the value 15
$i$j is assigned 4:5
Use of uninitialized value in concatenation (.) or string at ./getCurr
+entNeeds.pl line 74.
$athlete[$i,$j] is assigned the value
$bug is assigned the value 0.4
$i$j is assigned 4:6
Use of uninitialized value in concatenation (.) or string at ./getCurr
+entNeeds.pl line 74.
$athlete[$i,$j] is assigned the value
$bug is assigned the value 0.1
| [reply] [d/l] [select] |
|
|
The error lies in the fact that you are incrementing $j here:
$athlete[$i][$j++] = $bug;
The problem is that since $j is one larger than before, and thus you are not printing out the same thing (2 lines later) as what you just set. (ie $athlete[0][0] != $athlete[0][1]) so you get the warning.you might want to increment the $j by one at the end of the loop. update: I am afraid, I might have confused you so here goes. Let's pretend we are going through the inner loop on the first pass: $j = 0;
foreach my $bug (@row) {
#here $j == 0; so the following line would be
#$athlete[$i][0] = $bug;
$athlete[$i][$j++] = $bug
#at this poing the $j == 1 because of the $j++
#on the previous line.
print "\$i\$j is assignt $i:$j\n";
print "\@athlete[\$i,\$j] is assigned the value $athlete[$i][$j]\n";
#on the previous line you $j == 1 so you are refering to
#$athlete[$i][1] which is not the same as what you set
#but rather the value you will set the next time through.
. . .
if you change the print line to:print "\@athlete[\$i,\$j] is assigned the value $athlete[$i][$j-1]\n";
you would print the value you just set, which is what I think you are trying to do.
-enlil
| [reply] [d/l] [select] |
|
|
$i = 0;
while (@row = $qry->fetchrow)
{
print "\@row is assigned @row\n";
$j = 0;
foreach my $bug (@row)
{
$athlete[$i][$j] = $bug ;
print "\$i\$j is assigned $i:$j\n";
print "\$athlete[\$i,\$j] is assigned the value $athlete[$i][$j]
+\n";
print "\$bug is assigned the value $bug\n";
$j++;
}
$i++;
}
| [reply] [d/l] |
Re: Where is my foreach data going to?
by Roger (Parson) on Sep 18, 2003 at 00:56 UTC
|
@athlete[$i,$j++] = $bug ;
Is actually an array slice. You probably wanted this instead:
$athlete[$i,$j++] = $bug;
It's pretty easy to mistake array slices for array indices. | [reply] [d/l] [select] |
|
|
$athlete[$i,$j++] = $bug;
with warnings on? It doesn't mean at all what you thing
it means.
$ perl -wcle '$i = $j = 0; $athlete [$i, $j ++] = 1'
Multidimensional syntax $athlete [$i, $j ++] not supported at -e l
+ine 1.
Useless use of a variable in void context at -e line 1.
Name "main::athlete" used only once: possible typo at -e line 1.
-e syntax OK
If you want to use multi-dimensional arrays, you have to
use the correct syntax:
$athlete [$i] [$j ++] = $bug;
Abigail
| [reply] [d/l] [select] |
|
|
Your change yielded these results:
@athlete[$i,$j] is assigned the value 0.4 Small Bunch Grapes
$bug is assigned the value 32
$i$j is assigned 4:2
@athlete[$i,$j] is assigned the value 0.4 carb
$bug is assigned the value Medium Pear
$i$j is assigned 4:3
@athlete[$i,$j] is assigned the value 0.4 15
$bug is assigned the value carb
$i$j is assigned 4:4
@athlete[$i,$j] is assigned the value 0.4 0.4
$bug is assigned the value 16
$i$j is assigned 4:5
@athlete[$i,$j] is assigned the value 0.5 0.1
$bug is assigned the value 0.5
$i$j is assigned 4:6
@athlete[$i,$j] is assigned the value 0.5
$bug is assigned the value 0.2
To be honest, I'm more confused now than I was when I first made this post. | [reply] [d/l] |
|
|
You need to replace all @athlete[$i,$j] with $athlete[$i,$j], even with your print statement. Because the syntax @athelete[$i,$j] is wrong. ;-)
To understand why, you need to understand what is an array slice ...
| [reply] [d/l] [select] |
Re: Where is my foreach data going to?
by brotherdaniel (Novice) on Sep 18, 2003 at 01:32 UTC
|
OK, here's a reply to my own post. But it should reveal why I don't think it's a problem with data types. This will trim out some of the debugging code, but what you'll see it that only an occasional assignment is not made:
@row is assigned 31 Medium Orange carb 14 2 0.2
@athlete[$i,$j] is assigned the value
@athlete[$i,$j] is assigned the value Medium Orange
@athlete[$i,$j] is assigned the value carb
@athlete[$i,$j] is assigned the value 14
@athlete[$i,$j] is assigned the value 2
@athlete[$i,$j] is assigned the value 0.2
@row is assigned 42 1/2 c. (cooked) past carb 19.5 3.2 0.4
@athlete[$i,$j] is assigned the value 42 42
@athlete[$i,$j] is assigned the value
@athlete[$i,$j] is assigned the value carb
@athlete[$i,$j] is assigned the value 19.5
@athlete[$i,$j] is assigned the value 3.2
@athlete[$i,$j] is assigned the value 0.4
@row is assigned 26 1/2 c. canned peache carb 14 1 0
@athlete[$i,$j] is assigned the value 26 0.4
@athlete[$i,$j] is assigned the value 1/2 c. canned peache 1/2 c. cann
+ed peache
@athlete[$i,$j] is assigned the value
@athlete[$i,$j] is assigned the value 14
@athlete[$i,$j] is assigned the value 1
@athlete[$i,$j] is assigned the value 0
@row is assigned 6 White Bread III carb 24.5 4.1 2.3
@athlete[$i,$j] is assigned the value 6
@athlete[$i,$j] is assigned the value White Bread III 0
@athlete[$i,$j] is assigned the value carb carb
@athlete[$i,$j] is assigned the value
@athlete[$i,$j] is assigned the value 4.1
@athlete[$i,$j] is assigned the value 2.3
@row is assigned 20 Marias Spanish Rice carb 42.4 4.3 5
@athlete[$i,$j] is assigned the value 20
@athlete[$i,$j] is assigned the value Marias Spanish Rice
@athlete[$i,$j] is assigned the value carb 2.3
@athlete[$i,$j] is assigned the value 42.4 42.4
@athlete[$i,$j] is assigned the value
@athlete[$i,$j] is assigned the value 5
See what I mean? It just seems to almost be caching or writing out of order. I'm sure it's my mistake, but I sure don't know why it's doing this. These are the results from my original code base. | [reply] [d/l] |
|
|
It has everything to do with data types!
@athelete[$i,$j], $athelete[$i, $j] and $athelete[$i][$j] are completely different. Try to use the Data::Dumper to investigate why:
use strict;
use Data::Dumper;
my @array;
for (my $i=0;$i<2;$i++)
{
for (my $j=0;$j<2;$j++)
{
@array[$i, $j] = "$i.$j";
}
}
print "Case 1...\n";
print Dumper(@array);
for (my $i=0;$i<2;$i++)
{
for (my $j=0;$j<2;$j++)
{
$array[$i][$j] = "$i . $j";
}
}
print "Case 2...\n";
print Dumper(@array);
for (my $i=0;$i<2;$i++)
{
for (my $j=0;$j<2;$j++)
{
$array[$i, $j] = "$i . $j";
}
}
print "Case 3...\n";
print Dumper(@array);
You will get -
Case 1...
$VAR1 = undef;
$VAR2 = undef;
Case 2...
$VAR1 = [
'0 . 0',
'0 . 1'
];
$VAR2 = [
'1 . 0',
'1 . 1'
];
Case 3...
$VAR1 = '1 . 0';
$VAR2 = '1 . 1';
As you can see, only case 2 gives you what you want, a two dimensional array. | [reply] [d/l] [select] |
|
|
Just one point , when using Data::Dumper::Dumper() to dump an array or a hash, it is often better to pass a reference to the hash/array, as the output looks more like the original data structure - and you avoid the copying overhead of call-by-value vs call-by-refernce
use Data::Dumper;
my @array = (1,2,3,4,5,6,7);
print Dumper(\@array);
my %hash;
# below is a hash slice - you should learn about these
@hash{@array} = @array;# a hash whose keys == its values
print Dumper(\%hash);
results in the output
$VAR1 = [
1,
2,
3,
4,
5,
6,
7
];
$VAR1 = {
'7' => 7,
'1' => 1,
'2' => 2,
'3' => 3,
'4' => 4,
'5' => 5,
'6' => 6
};
which to my eyes seems nicer | [reply] [d/l] [select] |
|
|
Re: Where is my foreach data going to?
by Beechbone (Friar) on Sep 18, 2003 at 17:39 UTC
|
Ok, we cleaned up the @/$/[,]/[][] problem. But why don't you just write:
for ($i=0; $i<$qry->numrows; $i++) {
@row = $qry->fetchrow or warn '...';
print "\@row is assigned @row\n";
$athlete[$i] = [ @row ];
}
or even perlier:
for my $i (0 .. $qry->numrows - 1) {
@row = $qry->fetchrow() or warn '...';
$athlete[$i] = [ @row ];
}
or (I hate array subscripts):
for (1 .. $qry->numrows) {
@row = $qry->fetchrow() or warn '...';
push @$athlete, [ @row ];
}
ok, no2 looks better ;)
Update: Oops, and again i coded rusbish. Fixed code no3, now it no longer looks bad ;) | [reply] [d/l] [select] |