in reply to What makes good Perl code?

Just my 2 cents, I'm sure it can be improved a lot. I simply found that is more readable like this... and at least is a little more compact.
#!/usr/bin/perl -w use strict; use warnings; use feature qw(say); use English qw(-no_match_vars); BEGIN { $^W = 1; } sub BEGIN { if ($^W == 1) {say "Let's get started..."} else {die $@} } local $OUTPUT_AUTOFLUSH = 1; local $OUTPUT_RECORD_SEPARATOR = *\ ; print <<NOTE_ONE; I will calculate whatever you specify according to Ohm's law. What shall I calculate? Type either voltage, current, or resistance NOTE_ONE my $type_current = <<NOTE_TWO; Type the current of the circuit. Add mA at the end of your answer, if your answer is in milliAmps: NOTE_TWO my $type_voltage = "Now type the voltage of the circuit:"; my $type_resistance = "Type the resistance of the circuit:"; my $ohmlaw = "Ohm's law is V = IR, so "; my $i = 0; while ($i == 0) { my $calculation = <STDIN>; if ($calculation =~ /voltage/) { say $type_current; my $current = <STDIN>; say $type_resistance; my $resistance = <STDIN>; if ($current =~ /mA/) { $current =~ s/mA//; $current =~ s/(^\s+| )//; $current /= 1000; } else {()} say $ohmlaw . "the voltage of\nthe circuit is " . $current * $ +resistance . " volts."; ++$i; } elsif ($calculation =~ /current/) { say $type_resistance; my $resistance = <STDIN>; say $type_voltage; my $voltage = <STDIN>; say $ohmlaw . "the current of\nthe circuit is ". $voltage / $r +esistance . " amps., or " . $voltage /($resistance*1000) . " milliAmp +s."; ++$i; } elsif ($calculation =~ /resistance/) { say $type_current; my $current = <STDIN>; say $type_voltage; my $voltage = <STDIN>; if ($current =~ /mA/) { $current =~ s/mA//; $current =~ s/(^\s+| )//; $current /= 1000; } else {()} say $ohmlaw ."the resistance of\nthe circuit is ". $voltage / +$current . "ohms."; ++$i; } else {say "That is not a valid answer.\nRetype your answer."} }

Replies are listed 'Best First'.
Re^2: What makes good Perl code?
by Anonymous Monk on Aug 18, 2011 at 10:16 UTC
    #!/usr/bin/perl -w ... use warnings; ... BEGIN { $^W = 1; } sub BEGIN { if ($^W == 1) {say "Let's get started..."} else {die $@} }

    Why do you want to turn on warnings 3 times and then die if they're not turned on? use warnings; is sufficient for anything but an ancient version of perl, in which case you might need the -w switch.

    my $resistance = <STDIN>; if ($current =~ /mA/) { $current =~ s/mA//; $current =~ s/(^\s+| )//; $current /= 1000; }

    That's kind of a mess. First you match on mA and then remove mA, not to mention that it will fail on bad input. Consider an answer like 0 or "more amps than you'll ever know!" It's much better to extract the expected input and complain if you can't find it. The following is a quick, untested example...

    my $input = <STDIN>; my ($current) = $input =~ /^\s*[\d.]+\s+/ or do { error_stuff(); ... # next, redo, or return, as appropriate }; $input =~ /\s+mA\s*$/ and $current /= 1000;

      Gah, I'm an idiot...

      my ($current) = $input =~ /^\s*[\d.]+\s+/ or do {

      should be

      my ($current) = $input =~ /^\s*([\d.]+)\s+/ or do {

      or there won't be a capture of the number.