in reply to What is wrong with this code?

  1. Why use say then add explicit new lines at the end of the line?
  2. Why a series of while loops, especially as $type isn't changed from one loop to the next?
  3. Think about what happens in each loop if the body of the if is not executed (hint - what causes the loop to terminate?)
  4. The string returned by <> includes the new line character at the end of the line. You probably want to chomp before using entered strings as values.
  5. Why don't you "use warnings"?
  6. shift isn't going to do it for you for "paralellogram".

For a version of your program to ponder a while consider:

use 5.010; use strict; use warnings; my %types = ( square => {dimensions => ['side'], calc => \&calcSquare}, rectangle => {dimensions => ['width', 'height'], calc => \&cal +cRect}, parallelogram => {dimensions => ['base', 'height'], calc => \&cal +cRect}, ); say "I am an area calculator."; while (1) { say "Enter stop to stop or one of: ", join ' ', sort keys %types; print "What type of shape am I working with? "; my $type = <>; chomp ($type); last if lc $type eq 'stop'; if (!exists $types{lc $type}) { say "Sorry, I don't know about $type."; next; } my @dims; for my $dim (@{$types{$type}{dimensions}}) { print "Enter a value for $dim:"; my $value = <>; chomp $value; push @dims, $value; } say "The area or your $type is: ", $types{$type}{calc}->(@dims); } say "Thanks for using me. Come again sometime"; sub calcSquare { return $_[0] * $_[0]; } sub calcRect { return $_[0] * $_[1]; }

Whenever you find yourself writing essentially the same code over and over, consider either using a loop or using a subroutine to contain the common stuff. This example use a hash which contains a reference to the subs used to do the actual calculation and a list of the dimensions required for each shape. Adding a new shape is just add the calculation sub and a new line to the hash.

True laziness is hard work