rcd^_- has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I'm very new to perl and put this together real fast... I spent about 100 times as much effort trying to get it to work as I did typing it... help me ploxx? ^^

#!perl print "What is your name?\n"; chomp($name = <STDIN>); if ($name = 'larry') { print "You\'re Larry!\n" } elsif ($name = 'moe') { print "You\'re Moe!\n" } elsif ($name = 'curly') { print "You\'re Curly!\n" }

whenever I run it and enter an name it always comes back larry... I'm sure there's some glaring mistake that I've made but i cant find it.... -.- ty in advance.

Replies are listed 'Best First'.
Re: elsif failing
by GrandFather (Saint) on Sep 22, 2009 at 04:46 UTC

    The problem is that you are using the assignment operator '=' rather than an equality operator ('==' or 'eq'). Assignment returns whatever was assigned and 'larry' (the first string assigned) is a true value so the first if test always succeeds.

    If you find yourself writing the same code over and over again you should think about how you can rewrite it to avoid repeating yourself. In this case a look up table (hash for the initiated) is the answer. Consider:

    use strict; use warnings; my %names = (larry => 'Larry', moe => 'Moe', curly => 'Curly'); print "What is your name?\n"; chomp(my $name = <STDIN>); if (exists $names{lc $name}) { print "You\'re $names{lc $name}!\n" } else { $name = ucfirst $name; print "I don't know anyone by the name $name\n"; }

    Note that the hash keys are entered lower case but the hash values have the correct case and that the hash look up uses the lower case version of the given $name string. This lets names with characters of any case to match, but prints out the correct case.

    The other thing to note is how easy it is to add another bunch of names. You could even read them in from a file with just a little effort.


    True laziness is hard work
Re: elsif failing
by lamprecht (Friar) on Sep 22, 2009 at 04:31 UTC
    Hi,

    always start your script with

    use strict; use warnings;

    Numbers are compared using == for strings you need  eq


    Cheers Christoph
Re: elsif failing
by biohisham (Priest) on Sep 22, 2009 at 06:11 UTC
    Using the proper comparison operator makes a great difference, you're comparing strings hence your operator to use is "eq", if you were comparing numbers however, you would have used "==" instead, this said, you know by now that "=" is the assignment operator.

    using:

    use strict; use warnings;
    at the top of each program saves you a lot of trouble, notice, when the strictures are on you would have to declare your variables using "my" the first time the variable is brought to existence, this has got to do with proper scoping and serves also to save you headaches from typing errors in variable names

    Now here is how your program would look like after corrections. Notice I did not use escaping by \n to put an apostrophe in you're because it is (i.e ' ) not one of Perl's metacharacters.

    #!/usr/local/bin/perl use strict; use warnings; print "What is your name?\n"; chomp(my $name = <STDIN>); if ($name eq 'larry') { print "You're Larry!\n" } elsif ($name eq 'moe') { print "You're Moe!\n" } elsif ($name eq 'curly') { print "You're Curly!\n" }
    Just like GrandFather said, using a data structure like hashes is the answer to avoid repetitive code-writing. Another thing, Perl boasts of a capability called TIM TOWDY which means "There is more than one way to do it", and here is another way to do your program in addition, using another type of data structures called arrays to hold the names for you and the rest of the code just checks the condition when the name exists and prints it:
    #!/usr/local/bin/perl use strict; use warnings; my @names =qw(larry moe curly); print "What is your name\n"; chomp(my $name = <STDIN>); if(grep {/$name/} @names){ print "you're @{[grep {/$name/} @names]}!\n"; }else{ print "I don't know this name\n"; }
    Update: Hashes are more flexible to work with as GrandFather duly explained. I wish you a happy Perl programming, it is just real fun to learn Perl.

    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.

      A more interesting 'nother way to do it' is by dispatching methods. It's still a hash lookup under the hood, but is a fine technique to be aware of for some situations (adding verbs to a parser for example). Consider:

      use warnings; use strict; print "What is your name?\n"; chomp (my $name = ucfirst <STDIN>); my $obj = bless {}; my $call = $obj->can ("name$name"); if ($call) { $call->(); } else { print "I can't handle anyone by the name $name.\n"; } sub nameLarry { print "Hi Larry. Welcome\n"; } sub nameMoe { print "Hi Moe. Late again I see!\n"; } sub nameTim { print "Hi TIMTOWTDI. Still pursuing the alternative life style?\n" +; }

      The OP should note that while using an array and grep is an alternative technique, it's not a very good alternative because it doesn't scale well. That is, if there are a lot of names and the lookup needs to be done many times the 'linear search' that grep uses will slow processing down substantially. A small improvement can be made by using a for loop and using last to exit the loop as soon as a match is found, but that really doesn't redeem the array lookup where a hash or method dispatch could have been used.


      True laziness is hard work