CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Beginner:
beginner question

 



sttring
Deleted

Jan 1, 2001, 9:44 AM

Post #1 of 8 (804 views)
beginner question Can't Post

I just started learning perl. I got the book "Learning Perl" by Oreilly and am trying out some of their examples. Until this one all have worked fine. The code for it is:

#!/usr/local/bin/perl -w

%words = qw(
fred camel
barney llama
betty alpaca
wilma alpaca
);
print "\nWhat is your name? ";
$name = <STDIN>;
chomp ($name);
if ($name eq "Randal") {
print "Hello Randal! How good of you to be here!\n";
} else {
print "Hello $name!\n";
$secretword = $words{name};
print "What is the secret word? ";
$guess = <STDIN>;
chomp ($guess);
while ($guess ne $secretword) {
print "Wrong try again. What is the secret word? ";
$guess = <STDIN>;
chomp ($guess);
}
}


The error being returned from perl is

Use of uninitialized value in string ne at c:\windows\desktop\newperl.pl line 20, <STDIN> line 2.

What is the problem?

Thanks,
sttring



Mortimer
journeyman

Jan 1, 2001, 6:32 PM

Post #2 of 8 (789 views)
Re: beginner question [In reply to] Can't Post

This is because $secretword is a little *too* secret in this program, ie: it hasn't been defined anywhere. So $secretword is your `unititialized value'.


Code
#%words = qw(name secret fred camel barney llama betty alpaca wilma alpaca); ### 
%words = qw(fred camel barney llama betty alpaca wilma alpaca); ###

$updated_secretword="Dunno"; ###

print "\nWhat is your name? ";
$name = <STDIN>;
chomp ($name);

if ($name eq "Randal") {
print "Hello Randal! How good of you to be here!\n";
}
else {
print "Hello $name!\n";
#$secretword = $words{'name'} = "secret"; ###
$secretword = $words{'name'} = $updated_secretword; ###
print "What is the secret word? ";
$guess = <STDIN>;
chomp ($guess);
while ($guess ne $secretword) {
print "Wrong try again. What is the secret word? ";
$guess = <STDIN>;
chomp ($guess);
}
}
print "$words{'name'}\n";
print "$secretword\n";

You must initialize `$words{'name'}'. You can do this by hardcoding it into %words, ie:


Code
%words = qw(name secret fred camel barney llama betty alpaca wilma alpaca);

Or during execution which can be very handy, for example when different secretwords
are being generated from somewhere else...


Code
$secretword = $words{'name'} = $updated_secretword;

Here you can assign the value of $updated_secretword to $secretword, and also plonk it into %words.
Have a play around. Just comment/uncomment the lines indicated with ###.

Dave. (Wannabe Perl hacker).
www.dmscripts.com - davemortimer@one.net.au



sttring
Deleted

Jan 2, 2001, 1:53 PM

Post #3 of 8 (775 views)
Re: beginner question [In reply to] Can't Post

Hmm, well this was the example given in the book. Are you saying that the book is completely incorrect with their example? The book is written by Oreilly.

Regarding where you changed the contents of the hash;

by the line where it says

$secretword = $words{name};

Why does the word "name" need to be put into the hash? The word "name" in brackets is referring to any scalar value in the hash %name , not a scalar with the value "name".

Would it work if I changed the line to

$secretword = $words{%name};

Thanks,
sttring



Mortimer
journeyman

Jan 2, 2001, 5:38 PM

Post #4 of 8 (766 views)
Re: beginner question [In reply to] Can't Post

>Hmm, well this was the example given in
>the book. Are you saying that the book is
>completely incorrect with their example?
>The book is written by Oreilly.

Certainly not. I havn't even seen the book. What I am saying, is that Perl is telling
you it can't find `$words{name}' in the code you are running. That's because it hasn't
been initialized in %words, at least not in the code you submitted with your original post.
Within your program, you try to assign the value of `$words{name}' to `$secretword'. But
`$words{name}' doesn't exist.

>Regarding where you changed the contents
>of the hash;

>by the line where it says

>$secretword = $words{name};

>Why does the word "name" need to be put
>into the hash? The word "name" in brackets
>is referring to any scalar value in the
>hash %name , not a scalar with the value "name".

The part between the braces is a `key', which gives up a `value'. I think it would be easier
to understand if you define your hash lists in the following manner for the time being:


Code
%words = ("fred"=>"camel","barney"=>"llama", 
"betty"=>"alpaca","wilma"=>"alpaca");

Think of the `=>' as the key which opens the door to the value on it's right. Each key has a
name, to the left of the `=>'.

>Would it work if I changed the line to

>$secretword = $words{%name};

Did you try it?

The code I submitted with my first answer works, but you need to comment/uncomment the lines
indicated to make sure `$words{name}' exists. Anyway, to make things a little more simple, just run
your original code with the following hash:


Code
%words = qw(name secret fred camel barney llama betty alpaca wilma alpaca);

...or to make things clearer:


Code
%words = ("name"=>"secret","fred"=>"camel", 
"barney"=>"llama","betty"=>"alpaca","wilma"=>"alpaca");

Note the inclusion of the key-value pair `name secret' or "name"=>"secret".
In my last I was demonstrating how to initialize hash variables anonymously, making the
program more versatile.

Dave. (Wannabe Perl hacker).
www.dmscripts.com - davemortimer@one.net.au



sttring
Deleted

Jan 2, 2001, 8:16 PM

Post #5 of 8 (760 views)
Re: beginner question [In reply to] Can't Post

I added name and secret into the hash, but the script doesn't seem to recognize any password, except secret for any name I try, most likely because the line $secretword = $words{name}; is looking for the password for 'name'. The purpose of the line is to look in the hash %words for the $name and compare each specific username with the password its paired with, but it doesn't seem to be doing that.


In Reply To
Within your program, you try to assign the value of `$words{name}' to `$secretword'. But
`$words{name}' doesn't exist.

What do you mean, it doesn't exist? What doesn't exist? %words exists and name is referring to $name, or at least it's supposed to . How can I make that line look for the scalar $name, rather than for a value in the hash named 'name'?

I changed to $secretword = $words{name}; to $secretword = $words{$name}; and now everything is working with the usernames in the hash except when I type in a name that is not in the hash, it comes up with the error. Any suggestions?

Thanks,
sttring



Mortimer
journeyman

Jan 2, 2001, 11:41 PM

Post #6 of 8 (756 views)
Re: beginner question [In reply to] Can't Post

>I added name and secret into the hash, but the script
>doesn't seem to recognize any password, except secret

That's how it should be.

>for any name I try, most likely because the line
>$secretword = $words{name}; is looking for the password
>for 'name'. The purpose of the line is to look in the
>hash %words for the $name and compare each specific
>username with the password its paired with, but it
>doesn't seem to be doing that.

No. The program requires that only $guess be compared with
*one* value from the hash, `$words{name}'. The only word
you can use is `secret'. Anything else, and you'll be told
you're wrong. $name is not compared with anything in the
hash.

>>Within your program, you try to assign the value
>>of `$words{name}' to `$secretword'. But
>>`$words{name}' doesn't exist.

>What do you mean, it doesn't exist? What doesn't exist?
>%words exists and name is referring to $name, or at least...

If you look at your original post at the top of this page,
you'll find that $words{name} does not exist in %words.
$name is a seperate issue here. If your name is Randal, the
program welcomes you and exits. If you're someone else,
then you must know what the secret word is before it will
exit. This is controlled by the `while' loop.

>...it's supposed to . How can I make that line look for the
>scalar $name, rather than for a value in the hash named 'name'?

>I changed to $secretword = $words{name}; to
>$secretword = $words{$name}; and now everything is working...

I suspect that may have been the original intention of the
author.

>...with the usernames in the hash except when I type in a
>name that is not in the hash, it comes up with the error.

Which brings us back to my first answer, only this time it's
`$words{$name}' which is not defined in the hash.

So whichever way you look at it, the program is flawed.
Anyway, as the program in your original posting
stands, the only way for it to run without errors, is when
`$words{'name'}' is defined.
But even if it was the intention of the author to compare
`$guess' with `$words{$name}', (as it now looks to me, after I
tested your suggestion above), the program should provide some
sort of contingency for trapping an error which resulted from
the user entering a name which isn't even in the hash.
How are we to know? To be blunt, I think it's a crappy piece
of ten minute junk.

This code will trap the error in the latter case.
Paste it into your original program after:


Code
else{ 
print "Hello $name!\n";

Paste this code:


Code
    if(exists($words{$name})){ 
$secretword = $words{$name};
}
else{
print "Bye bye";
exit;
}

Now isn't that an appropriate ending.

All the best,

Dave. (Wannabe Perl hacker).
www.dmscripts.com - davemortimer@one.net.au



sttring
Deleted

Jan 3, 2001, 3:45 AM

Post #7 of 8 (751 views)
Re: beginner question [In reply to] Can't Post

Thanks, with your latest code, it now says hello $name and then bye bye if I put in a name that isn't in the hash. One question though. In your code you wrote
exit;
Is it necessary to have that in the code for it to work? If so, what does it do? I haven't learned about exit yet. Does it just stop the script where it is and end it? The code from the book really is crap. I appreciate all your help.

Thanks,
sttring


sttring
Deleted

Jan 3, 2001, 4:28 AM

Post #8 of 8 (750 views)
Re: beginner question [In reply to] Can't Post

Just noticed a comment in the book. It says if the name is not found then $secretword will be an empty string.

There is also a comment at the bottom of the page that says "Well OK, it's the undef value, but it looks like an empty string to the eq operator. You'd get a warning about this if you used -w on the command line, which is why it should not be used here.

So it seems that the script is supposed to have errors if run with the -w switch. I tried without -w and it doesn't return any errors.

sttring


 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives