in reply to Problem in printing lastname and firstname

I really don't want to be a layout enforcer. Since no one has brought it up, please Clean your room before posting.

You can use whitespace and indenting to convey helpful information. We want to help - make it easy on us.

#!/usr/bin/perl use strict; use warnings; my $input = ''; my %nme = (); my $fn = ''; my $ln = ''; while() { print "enter the name\n"; chomp($input=<STDIN>); if($input ne '') { ($fn, $ln) = split('',$input); print "$fn, $ln\n"; $nme{$ln} = $fn; } else { last; } foreach my $lastname(sort keys %nme) { print "$lastname, $nme{$lastname}\n"; }
This is much easier to read and, we see right there you're missing a final curly. I'm sure that's a copy-n-paste error, but wouldn't it be nice if you showed syntactically correct code to people who are helping you (at the very least it keeps us away from a red herring).

Always use strict; and use warnings;. Even if it would not have helped you here, you need to get into the habit. You took the time to preset your vars, there is no reason not to have strict and warnings on.

UPDATE: fixed link - Thanks Albannach and added strict and warnings for demonstration - Thanks Grandfather

grep
XP matters not. Look at me. Judge me by my XP, do you?

Replies are listed 'Best First'.
Re^2: Problem in printing lastname and firstname
by GrandFather (Saint) on Nov 18, 2006 at 21:31 UTC

    In the same vein I'd advise the OP to constrain the scope of his variables to make it easier to see where they are used and to avoid the bogus initialisations.

    Always initialising variables seems like a good idea, but is only appropriate where the variable is being given a default value. If it is intended that the initial value will always be replaced, it is much better not to provide a bogus intial value. Perl's use warnings; "undef used" warning gives an immediate heads up that there is a path or condition in your code that you hadn't anticipated is you leave variables uninitialised until you have a sensible value for them.

    Reworking the code again with that in mind and after fixing various issues that arise during testing you might end up with:

    #!/usr/bin/perl use strict; use warnings; my @nme; # Input loop while ((print "Enter the name: "), defined (my $input = <STDIN>)) { chomp $input; last if ! length $input; # Exit loop on empty line my ($fn, $ln) = split /\s+/, $input, 2; if (! defined $fn) { print "Blank name ignored\n"; next; } $ln ||= '_missing_'; # Provide missing name print "$fn, $ln\n"; push @nme, "$ln, $fn"; } # Print loop print "$_\n" foreach sort @nme;

    Note too the use of the comma operator in teh while loop expression to get the prompt output each time through the loop. Not a highly recommended technique, but can be less ugly and more cogent than many of the alternative ways of achieving the same effect.

    Note too that the hash changed into an array. It's quite possible for two people to have the same last name. In fact it is even possible for people to have the same name. Names are tricky. ;)


    DWIM is Perl's answer to Gödel
      Note too the use of the comma operator in the while loop expression to get the prompt output each time through the loop.Not a highly recommended technique, but can be less ugly and more cogent than many of the alternative ways of achieving the same effect.

      On *nix I usually set up my prompt outside the while loop along with another string of returns and spaces to erase the prompt once I drop out of the loop. Like this

      my $prompt = q{Enter name (<Ctrl-D> to exit) : }; my $dePrompt = qq{\r} . q{ } x (length($prompt) + 2) . qq{\r}; while (1) { print $prompt; last if eof STDIN; chomp(my $response = <STDIN>); # Do something with $response here ... } print $dePrompt;

      This has the advantage of cleaning up the last prompt displayed before returning to a shell prompt or some further output from the script. It does not work so well under MS Windows as it seems you have to do <Ctrl-Z><Enter> to signal EOF and that throws a line before you can erase the prompt. Thus, you may as well dispense with the $dePrompt part of it there.

      I am not sure why you do defined (my $input = <STDIN>). Will it not always be defined, even with just hitting <Enter> as $input will always contain at least a newline? Perhaps I'm missing something but I would have thought you'd only have to worry about definedness after the chomp.

      Cheers,

      JohnGG