You're running into a common difficulty for newer programmers. Here are some good rules of thumb to keep in mind:
- Variable starts with a $: You're asking for a "scalar" value.
- Variable starts with a @: You're asking for an array of scalars.
- Variable starts with a %: It's a hash.
- Square braces - [ and ] - with the variable often indicates that you're accessing an array element.
- Curly braces - { and } - with the variable names means you're trying to access a hash element.
That's not exactly comprehensive, but it usually holds. For example, when you had the following line:
$secretword=$words{$name};
The curly braces should indicated that you were expecting "words" to be a hash. So, when you have a problem, you go back and look at how words is defined. In this case, it's declared as an array with the @ symbol.
If you had use strict at the top of your program, you would have received a fatal error for trying to access a "words" hash that was undeclared. Actually, you would have gotten errors earlier when you tried to assign elements to the @words array. I know that's not covered right away in the book you are using, but it's a good practice to get into (along with using warnings, the -w switch). Using strict and warnings will save you many hours of debugging and, in this case, an error would have occured long before it did, thus allowing you to have a better idea what's actually causing the error.
Unfortunately, the above information is a very simplistic treatment of the issues, but it's some good stuff to always keep in mind when you are first starting out.
Cheers,
Ovid
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats. | [reply] [d/l] |
First off, in your first line you're defining an array "@words" when what I think you want is a hash, "%words". Below, in the "$words{$name}" part, that wouldn't work as a lookup with the array @words, which is what you have now. Change the "@" to a "%" and your code should work.
I guess the thing to learn here is that problems aren't always obvious. If you start developing your scripts with use strict; and perl -wT it will initially seem like a pain in the butt (but) problems like this will just pop out at you.
Good luck!
Here's your "llama" code, fixed.
#!/usr/bin/perl
use strict;
my(%words,$name,$secretword,$words,$guess);
%words=qw(
fred camel
barney llama
betty alpaca
wilma alpaca
);
print "What is your name?\n";
$name=<STDIN>;
chomp ($name);
if ($name eq "Randal")
{
print "Hello, Randal! Welcome!\n"
} else {
print "Hello $name.\n";
$secretword=$words{$name}; # use {} for hash
if ($secretword eq ""){ # gives me an error around here
$secretword="stupid"; #default secret word
}
print "What is the secret word?";
$guess =<STDIN>;
chomp($guess);
while ($guess ne $secretword){
print "Wrong, try again.\n";
$guess=<STDIN>;
chomp ($guess);
}
}
| [reply] [d/l] [select] |
That code, while it found the main code error, will still
sometimes show the error message.
$secretword=$words{$name};
if ($secretword eq ""){
$secretword="stupid";
}
If $name is not found in the hash %words, then
$secretword will be undefined and will produce the error mentioned
when used as if defined. If you however test for the
definedness of $secretword you will be closer to the
original aim.
if (defined $secretword) {
$secretword = 'stupid';
}
In perl style I'd probably write:
$secretword = $words{$name} || 'stupid';
But that is a matter of choice. | [reply] [d/l] [select] |
Besides the other great things already said in this thread...
This example in llama2 will not be in llama3. I can speak with authority on that. {grin}
-- Randal L. Schwartz, Perl hacker | [reply] |
I wont restate what was already said, but Good Luck on Learning Perl! | [reply] |
Nobody mentioned this, but this kind of question should go
into Seekers of Perl Wisdom. This area of Perlmonks is for discussion of topics related to the website .. how it
should be run, how to improve it, etc. Specific code questions are for Seekers. | [reply] |