ms238 has asked for the wisdom of the Perl Monks concerning the following question:

Hi, I'm trying to learn Perl and every now and then I run into an error on a script that I think ought to be correct. I'm not sure if I have an obvious error somewhere or not but my IDE keeps saying there is an error at line 6 (error: Can't modify not in scalar assignment). I was thinking maybe my close parenthesis or semicolon at the end of the hash is off. However, modifying that line/area doesn't seem to fix things. I'm posting the code for some help please.
!#/usr/bin/perl %words = qw(Sarah cat Bob dog Ronald apple Eric banana); print "What is your name?"; $name = <STDIN>; chomp ($name); if ($name eq "Jerry") { print "Hi, Jerry! Have a good day!\n";} else {print "Hello, $name!\n"; #normal greeting $secretword = $words{$name}; #get the secret word print "Guess the secret word.\n"; $guess = <STDIN>; chomp ($guess); while ($guess ne $secretword) { print "I'm sorry. That is not the correct word. Please try again. + What is the secret word?"; $guess = <STDIN>; chomp ($guess); } }

Replies are listed 'Best First'.
Re: Creating a Hash Syntax Error
by AppleFritter (Vicar) on Jul 27, 2014 at 12:14 UTC

    The hashbang line is your problem; !#/usr/bin/perl should be #!/usr/bin/perl. The way you wrote it, "/usr/bin/perl" is interpreted as a comment, and the ! becomes an operator applied to the next line:

    !%words = qw(...);

    And obviously that's not valid Perl.

    Since you're new to Perl, here's some general tips as well: format your script nice and readable, and use strict; and use warnings; to catch many common mistakes, typos and so on.

      Thanks, Apple Fritter, for noticing. It worked!
Re: Creating a Hash Syntax Error
by aitap (Curate) on Jul 27, 2014 at 12:15 UTC

    Your first line of script is invalid. For UNIX-like system, in order to recognise your script as executable, the first two bytes of it must be "#!", and the remaining of the line must be the path to your interpreter. Thus, it looks like a comment and does not affect the execution of your program (actually, Perl reads the shebang line, but this is irrelevant now).

    Swap the "#" and "!", so Perl doesn't interpret it as a negation (! %words = ( ... );). perl -MO=Deparse (use O 'Deparse') helped me to find it.

      Hi aitap, Thanks for your reply. I'm interested in trying out O Deparse so I checked out the description o the website. It looks like I can enter my Perl program in there so that they can search it for errors and improve the code. Is that right? If so, I don't see where I input my code... Could you provide some basics on using this website that might help me learn Perl? I'd certainly appreciate it.

        I'm not sure of I understand you correctly. AFAIK, http://perldoc.perl.org is not capable of checking Perl core for errors. But you can do it on your machine:

        1. Run perl -c yourfile.pl. Perl will compile your program and check for mistakes which can be found without running most of it.
        2. If if gave you an error message which you can't understand, try use diagnostics; (or add -Mdiagnostics command line switch) or ask splain program for help.
        3. If you still don't understand why Perl doesn't like some particular line (e.g. it happens on a completely valid line, empty line, or end-of-file), or the program works incorrectly without throwing errors, maybe your understanding of the program differs from Perl's at some earlier point. Run perl -MO=Deparse,-p yourfile.pl (which has the effect of temporaly adding use O 'Deparse', '-p'; to the file) and check if Perl understands you correctly. Additional '-p' option enables additional parentheses which cause incorrect program behaviour often.
        4. Indenting your programs now helps to understand them later. Your computer can indent a Perl program for you using perltidy.
        5. Everything works, but you are not sure whether you did something right? perlcritic will thoroughly search your code for common mistakes and suggest best practices.
        See also: basic debugging checklist.

Re: Creating a Hash Syntax Error
by Laurent_R (Canon) on Jul 27, 2014 at 14:29 UTC
    You've been given the right answer to your problem, but I would suggest that you learn to indent your code correctly. Although wrong indentation does not prevent your code from running, right indentation is absolutely essential to programming correctly. An additional recommendation would be to use:
    use strict; use warnings;
    for any program having more than one line. These two bits of advice will save you hours of debugging time if you follow them.

    Please don't hesitate to ask if you don't understand what I am talking about or why I am saying such things.

Re: Creating a Hash Syntax Error
by 1s44c (Scribe) on Jul 27, 2014 at 18:22 UTC

    Indent your code, it makes it a lot more readable and will help you to find errors. Use warnings and strict. Declare all variables. The fat arrow '=>' makes hash assignments more readable. Chomp assignments to save a line.

    There was nothing wrong with what you posted except the shebang line. A bit of polish makes it a lot more maintainable.

    Here is a cleaned up version:

    #!/usr/bin/perl use warnings; use strict; my %words = ( Sarah => 'cat', Bob => 'dog', Ronald => 'apple', Eric => 'banana' ); print "What is your name?"; chomp (my $name = <STDIN>); if ($name eq "Jerry") { print "Hi, Jerry! Have a good day!\n"; } else { print "Hello, $name!\n"; #normal greeting my $secretword = $words{$name}; #get the secret word print "Guess the secret word.\n"; chomp (my $guess = <STDIN>); while ($guess ne $secretword) { print "I'm sorry. That is not the correct word. Please try aga +in.\nWhat is the secret word?"; chomp ($guess = <STDIN>); } }
      Thanks, airtap, Laurent_R and 1s44c. I will have to start indenting better. I have noticed that in a lot of programs, the left curly bracket is on the line above the print command and the right curly bracket is below it--instead of all on the same line. I was wondering why it isn't on the same line--unless it makes it easier to see if you left off a left or right curly bracket. I appreciate everyone that gave me help on this.