Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

hash problems

by weglarz (Novice)
on Sep 20, 2010 at 16:21 UTC ( #860872=perlquestion: print w/replies, xml ) Need Help??

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

Hello Perl Monks. I am new to Perl Monks and somewhat new to Perl itself. I coded Java for a couple years and then stopped. I recently began working in networking and have been using a unix shell to do some stuff and decided to start learning perl. Anyways, I am writing a program just to learn a bit about hashes and the different operators that work on hashes. I have encountered a couple errors, and I have been scratching my head all morning to try and figure them out. Please let me know what you think. Sorry if this is should be completely obvious to me... as I said I'm relatively new to Perl.

#!usr/bin/local/perl %passwords = {"Matt", "s1k1d52", "scuzzy", "2ab928", "Marky", "s8291s" +, "Jeb", "jeb23"}; delete $passwords{"jeb"}; if(exists $passwords{"Matt"}){ print("$passwords{"Matt"} is my password."); } if(defined $passwords{"scuzzy"}){ print($passwords{"scuzzy"} . " IS defined!"); } print("%passwords are everyone's passwords!");
Bareword found where operator expected at passhash.pl line 9, near ""$ +passwords{"Matt" (Missing operator before Matt?) String found where operator expected at passhash.pl line 9, near "Matt +"} is my password."" syntax error at passhash.pl line 10, near "}" Missing right curly or square bracket at passhash.pl line 17, at end o +f line Execution of passhash.pl aborted due to compilation errors.

Also, it says that I have a curly cue missing but I counted an even amount... am I missing something? Thanks again.

Replies are listed 'Best First'.
Re: hash problems
by Your Mother (Archbishop) on Sep 20, 2010 at 16:40 UTC

    The first problem is you used braces {} instead of parens () to define your hash. So you're making a hash reference and putting it into the hash as a single element. Then you're using double quotes without escaping them "within" double quotes. E.g., "This won't "work"." You can use the quote operators like qq and q, you can escape them like \"work\", or you can omit them since they aren't needed for simple hash keys.

    Here is your code with the parens and strict and warnings on + general Perl idiom/style changes.

    use warnings; use strict; my %passwords = ( Matt => "s1k1d52", scuzzy => "2ab928", Marky => "s8291s", Jeb => "jeb23" ); delete $passwords{jeb}; # <-- Update, MidLifeXis notes the casing in " +jeb" is wrong. if( exists $passwords{Matt} ) { print "$passwords{Matt} is my password.\n"; } if( defined $passwords{scuzzy} ) { print $passwords{scuzzy} . " IS defined!\n"; } print join(", ", values %passwords), " are everyone's passwords!\n";
Re: hash problems
by BioLion (Curate) on Sep 20, 2010 at 16:41 UTC

    All it is is that your line: print("$passwords{"Matt"} is my password."); is being interpreted as :

    print("$passwords{"Matt"} is my password."); ^-- string -^ ^- another string-^
    Effectively making 'Matt' a bareword (i.e. not a function, string etc...)

    Always remember to use warnings and strict (and diagnostics for more info on any error messages).

    Check out perldata for info on string interpolation... Hope this helps,

    Just a something something...
Re: hash problems
by toolic (Bishop) on Sep 20, 2010 at 16:42 UTC
    One problem is that you haven't escaped your double quotes in your print call. Try using qq:
    print(qq($passwords{"Matt"} is my password.));

    Another problem is that you should use parentheses, not curly braces, when assigning to a hash:

    %passwords = ("Matt", "s1k1d52", "scuzzy", "2ab928", "Marky", "s8291s" +, "Jeb", "jeb23");

    A debugging tip is to use Data::Dumper to display hashes:

    use Data::Dumper; print Dumper(\%passwords);

    See also:

Re: hash problems
by kennethk (Abbot) on Sep 20, 2010 at 16:49 UTC

    Welcome to the monastery, and welcome back to coding.

    You are doing your assignment incorrectly.

    %passwords = {"Matt", "s1k1d52", "scuzzy", "2ab928", "Marky", "s8291s", "Jeb", "jeb23"};

    should read

    %passwords = ("Matt", "s1k1d52", "scuzzy", "2ab928", "Marky", "s8291s", "Jeb", "jeb23");

    Parentheses specify a list, where as curly brackets in a variable assignment specify a hash reference (See perlreftut). A reference is a scalar that points to a hash, in the same vein as (but different than) a pointer. A read through of perldata might clarify the nature of variable types in Perl.

    Are you working from a book? I ask because there are a few stylistic issues that may hinder your learning. Of course, all of this is subjective.

    1. Especially coming from a strongly typed background like Java, you will probably want to use strict and warnings. See Use strict warnings and diagnostics or die for a good discussion of what it can do for you.
    2. On line 9, you have a problem with interpolation because you have used double-quotes for both your key stringification and for wrapping your output text. Easiest in this case would be just skipping the quotes around your key - Perl will automatically convert things that look like keys into strings for hash access.
    3. You'll need to explicitly include newlines in your print statements if you don't want them to run together. A double-quoted escaped n ("\n") does the trick.
    4. The contents of a hash will not interpolate in a double-quoted context. You'll need to more explictly format your output.

    The version of your script that I would write would look more like:

    #!usr/bin/local/perl use strict; use warnings; my %passwords = (Matt => "s1k1d52", scuzzy => "2ab928", Marky => "s8291s", Jeb => "jeb23", ); delete $passwords{jeb}; if(exists $passwords{Matt}){ print("$passwords{Matt} is my password.\n"); } if(defined $passwords{"scuzzy"}){ print("$passwords{scuzzy} IS defined!\n"); } print "\nEveryone's passwords:\n"; while (my ($key,$value) = each %passwords) { print "$key => $value\n"; }

      I actually have a couple more questions. For one, what does the => operator do? Also, could you please explain these lines a bit(specifically "each %passwords"):

      while (my ($key,$value) = each %passwords) { print "$key => $value\n";

      Thanks again.

        A very handy skill in learning Perl is gaining familiarity with documentation. I personally use the Perl documentation hosted on http://perl.org with associated hook-up to my browser search box to keep it immediately on hand. There's also the perldoc command-line utility, ActiveState bundles html-ified docs with its version, and I'm sure a plethora of other options.

        For operators, there's perlop. Within that document, the => operator is documented under Comma Operator. It is identical to a comma, except to transforms a bareword left-hand argument to a string. Specifically,

        The => operator is a synonym for the comma except that it causes its left operand to be interpreted as a string if it begins with a letter or underscore and is composed only of letters, digits and underscores.
        Thus it allows:

        my %passwords = ("Matt" , "s1k1d52", "scuzzy" , "2ab928", "Marky" , "s8291s", "Jeb" , "jeb23", );

        to be written as

        my %passwords = (Matt => "s1k1d52", scuzzy => "2ab928", Marky => "s8291s", Jeb => "jeb23", );

        which I find to be more intuitive.

        The each function has a bit of magic in it. When called with a hash, it will set an iterator in the hash and returns a key, value pair. Each subsequent call (assuming you don't use another function that sets an iterator) returns another key/value pair until they are exhausted, at which time it will return and empty list or undef depending on context. Thus, a while(each) will systematically traverse a hash. On each iteration, I use list assignment to store the key/value pair and then output them in an interpolated string. The examples in each are likely more clear than any explanation I can give.

Re: hash problems
by MidLifeXis (Monsignor) on Sep 20, 2010 at 17:14 UTC

    delete $passwords{"jeb"};

    I am not sure if this is intentional or not, but "jeb" ne "Jeb".

    --MidLifeXis

Re: hash problems
by LanX (Sage) on Sep 20, 2010 at 16:43 UTC
    at the first spot and without deep analysis:

    1. plz start your scripts with use strict; and use warnings;.

    2.  %passwords = { is most certainly wrong, use parens for hash (lists), curlies are for hash {references}

    3. you're mixing doublequotes in the variable interpolation:

    print("$passwords{"Matt"} is my password.");
    , no need for them when adressing hash-keys:
    print("$passwords{Matt} is my password.")

    Cheers Rolf

Re: hash problems
by Anonymous Monk on Sep 20, 2010 at 17:12 UTC

    Don’t worry ... it takes a little time to recover from Java.   ;-)

    For a little while, you walk around like the Scarecrow in The Wizard Of Oz, singing. “If I only had a brain-n-n-n...”

    But look on the bright side.   Since you did make it out of there eventually, it was only Purgatory ...

Re: hash problems
by umasuresh (Hermit) on Sep 20, 2010 at 16:49 UTC
    In addition to all the other monks great suggestions, always  use Data::Dumper module to see what is in your hash.
    use Data::Dumper; ... ... ... print Dumper(\%hash);
Re: hash problems
by weglarz (Novice) on Sep 20, 2010 at 16:58 UTC

    Thank you all for your great responses and welcomes! It's certainly good to be back and coding! I am having a very good time with Perl. I am actually learning using a website that fits my learning style pretty well. I am going to order a book soon that I have heard is good for beginners: "Learning Perl". Thanks again and I look forward to interacting with you all on a regular basis, although hopefully later on on the other side of the fence!

    ~Weg
Re: hash problems
by changma_ha (Sexton) on Sep 21, 2010 at 06:25 UTC

    Hi Weglarz . Hope the following code will help

    #! /usr/bin/perl use strict; use warnings; use Data::Dumper; my %passwords = ("Matt", "s1k1d52", "scuzzy", "2ab928", "Marky", "s829 +1s", "Jeb", "jeb23"); delete $passwords{"jeb"}; if(exists $passwords{Matt}){ print($passwords{Matt}. "is my password.\n"); } if(defined $passwords{scuzzy}){ print($passwords{scuzzy} . " IS defined!\n"); }else{ print("%passwords are everyone's passwords!\n"); }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://860872]
Approved by kennethk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2021-10-19 21:26 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My first memorable Perl project was:







    Results (77 votes). Check out past polls.

    Notices?