Why this warning?

S

Sal

#!/usr/bin/perl

use strict;
use warnings;

my %sum = {};
for (my $i = 1; $i <= 6; $i++) {
for (my $j = 1; $j <= 6; $j++) {
for (my $k = 1; $k <= 6; $k++) {
my $tot = $i+$j+$k;
my $key = "$i " . "$j " . "$k ";
$sum{$key} = $tot;
print "$i " . "$j " . "$k " . " $tot\n";
}
}
}

foreach my $key (sort keys %sum) {
print "$key => $sum{$key}\n";
}

When the above is executed it first prints the entire hash, then
returns the error:

Use of uninitialized value $sum{"HASH(0x95fe818)"} in concatenation
(.) or string at ./3dice.pl line 19.
HASH(0x95fe818) =>

Why is the last hash value blank?
 
X

Xho Jingleheimerschmidt

Ben said:
This line is wrong. {} creates a new anonymous hashref; this is then
stringified and inserted into the hash as a key with no value.

And my version of perl even generates the warning "Reference found where
even-sized list expected".

Since the Sal seems to be using a newer Perl than mine (5.8.8), I would
think he would have gotten a similar warning.

Xho
 
K

Keith Thompson

Sal said:
#!/usr/bin/perl

use strict;
use warnings;

my %sum = {};
for (my $i = 1; $i <= 6; $i++) {
for (my $j = 1; $j <= 6; $j++) {
for (my $k = 1; $k <= 6; $k++) {
my $tot = $i+$j+$k;
my $key = "$i " . "$j " . "$k ";
$sum{$key} = $tot;
print "$i " . "$j " . "$k " . " $tot\n";
}
}
}

foreach my $key (sort keys %sum) {
print "$key => $sum{$key}\n";
}

When the above is executed it first prints the entire hash, then
returns the error:

Use of uninitialized value $sum{"HASH(0x95fe818)"} in concatenation
(.) or string at ./3dice.pl line 19.
HASH(0x95fe818) =>

Why is the last hash value blank?

I get:

Reference found where even-sized list expected at ./tmp.pl line 6.
[... contents of hash...]
Use of uninitialized value $sum{"HASH(0x9c6b880)"} in concatenation (.)
or string at ./tmp.pl line 19.

Probably the first warning scrolled off your screen before you were
able to see it. Changing 6 to 2 would have avoided that problem; so
would directing the output to a file or sending stdout to /dev/null
(or your system's equivalent) so you can see the warnings on stderr.

The problem is that {} isn't an empy list; it's a reference to
an empty hash. As a reference, it's a single scalar, so you're
assigning an odd number of elements (namely 1) to your hash.

(What's happening, I think, is that you get a hash with a single
key/value pair; the key is a stringized hash reference and the
value is undef. But the details don't really matter much, since
it's wrong in the first place.)

Change {} to () and you should be ok.

Incidentally, rather than:
my $key = "$i " . "$j " . "$k ";
I would have written:
my $key = "$i $j $k ";
(and probably left off the trailing blank).
 
U

Uri Guttman

S> #!/usr/bin/perl
S> use strict;
S> use warnings;

good.

S> my %sum = {};

very bad and wrong and makes a warning. {} is an anon hash reference,
not how you clear a hash. first off you don't need to assign to a my
hash as it will be empty when declared. if you do need to clear it you
assign the empty list () to it.

S> for (my $i = 1; $i <= 6; $i++) {

for my $i ( 1 .. 6 ) {

much clearer and also faster.

S> for (my $j = 1; $j <= 6; $j++) {

ditto

S> for (my $k = 1; $k <= 6; $k++) {

ditto

S> my $tot = $i+$j+$k;

ever heard of white space?

S> my $key = "$i " . "$j " . "$k ";

ever heard of interpolation? "$i $j $k ";

S> $sum{$key} = $tot;
S> print "$i " . "$j " . "$k " . " $tot\n";

ditto

uri
 
U

Uri Guttman

BM> Oh, but why do that when you can use an obscure Perl 4 feature instead?

BM> $sum{$i, $j, $k} = $i + $j + $k;

the hell with obscure! i lived on using pseudo multilevel hashes in
perl4. i did a major project where i did tons of that, used globs and
symrefs too to manage a massive tree, scan it and print stuff. i even
gave a talk about it at yapc::montreal. i still have the code from 17
years ago. not too useful now but nostalgic for sure.

uri
 
S

Sal

  S> for (my $i = 1; $i <= 6; $i++) {

for my $i ( 1 .. 6 ) {

much clearer and also faster.
####### Excellent idea!!!!
  S>   for (my $j = 1; $j <= 6; $j++) {
  S>       my $key = "$i " . "$j " . "$k ";

ever heard of interpolation? "$i $j $k ";
######## Made that change too.

Thanks to all on this forum who have taken the time to assist me. You
guys are great! After C/C++, Java, PHP, and dabbling a little in
Python, Perl is becoming my favorite language. I honestly don't
understand all the hype about Python.
 
J

Justin C

#!/usr/bin/perl

use strict;
use warnings;

my %sum = {};
for (my $i = 1; $i <= 6; $i++) {
for (my $j = 1; $j <= 6; $j++) {
for (my $k = 1; $k <= 6; $k++) {
my $tot = $i+$j+$k;
my $key = "$i " . "$j " . "$k ";
$sum{$key} = $tot;
print "$i " . "$j " . "$k " . " $tot\n";
}
}
}

foreach my $key (sort keys %sum) {
print "$key => $sum{$key}\n";
}

When the above is executed it first prints the entire hash, then
returns the error:

Use of uninitialized value $sum{"HASH(0x95fe818)"} in concatenation
(.) or string at ./3dice.pl line 19.
HASH(0x95fe818) =>

Why is the last hash value blank?

Probably because in your declaration of the hash you have declared the
hash to be {}, you then add other keys and values to the hash. If you
declare the hash thus:
my %sum;

instead then I think you will find all as you expect it to be. Didn't
perl warn you "Reference found where even-sized list expected at
untitled line 6."? Mine did.

Justin.
 
S

Steve C

Sal said:
Thanks to all on this forum who have taken the time to assist me. You
guys are great! After C/C++, Java, PHP, and dabbling a little in
Python, Perl is becoming my favorite language. I honestly don't
understand all the hype about Python.


Python programmers would point to your parens problem as a perfect example
of why Python is preferred. Perl programs are perplexing. You have to
parse a lot of punctuation to program Perl.
 
M

Mart van de Wege

F> Sal said:
Python programmers would point to your parens problem as a perfect example
of why Python is preferred. Perl programs are perplexing. You have to
parse a lot of punctuation to program Perl.

Rigghht. Never miscounted parens on a function that expects a tuple as
argument?

Or forgotten the comma in a single-element tuple?

All languages have their warts.

Mart
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,586
Members
45,096
Latest member
ThurmanCre

Latest Threads

Top