in reply to Improve my Code: Subroutines

Total agreement with CountZero and ikegami, and with most of what hangon says, plus a couple "new" ideas:
use strict; use warnings; use Math::Trig; # why settle for less (precision)? my ( @sigmas, @rads ); my ( $a1, $c ) = ( 1.18, .28e6 ); my $i = 1; while ( $i < 20 ) { my $r = $i * 1e-6; push @rads, $r; push @sigmas, pi * ($r**2) * $a1 * (1-exp(-$c*$r)); $i += 2; } while ( $i < 100 ) { my $r = $i * 1e-6; push @rads, $r; push @sigmas, 2 * pi * ($r**2); $i += 2; } for $i ( 0 .. $#rads ) { printf "rad= %8.3g sigma= %8.3g\n", $rads[$i], $sigmas[$i]; }
That changes the output format, so that it's easier to see the relationships between "rad" and "sigma" values.

It also shows a clean alternative to the C-style for loop, which some monks consider to be rather gauche. (Don't get me wrong -- C-style for loops have their place, but it tends to be a very small place, rarely visited by Perl hackers.)

UPDATE: Oops -- I just realized that your focus for this thread is on subroutines, and I completely avoided that part of today's lesson. Just replace the arithmetic expressions with sub calls that take "$r" as the sole parameter, and trim down the subs themselves as explained in the other replies.

Oh, and pick a name other than "$a" for the "1.18" constant -- perl has a global $a variable that is used by the built-in "sort" function. (I've updated my own code here to follow this advice.)

Okay, last update -- I decided/realized that all the repetition in the two while loops was silly, so here it is again (with subs; note how the return value of the sub is simply the value of the last expression in the sub -- you could add "return" there, but it isn't needed):

use strict; use warnings; use Math::Trig; # why settle for less (precision)? my ( @sigmas, @rads ); my $i = 1; while ( $i < 100 ) { my $r = $i * 1e-6; push @rads, $r; push @sigmas, ( $i < 20 ) ? sigmalo( $r ) : sigmahi( $r ); $i += 2; } for $i ( 0 .. $#rads ) { printf "rad= %9.4g sigma= %9.4g\n", $rads[$i], $sigmas[$i]; } sub sigmalo { my ( $r ) = @_; my ( $a1, $c ) = ( 1.18, .28e6 ); pi * ($r**2) * $a1 * (1-exp(-$c*$r)); } sub sigmahi { my ( $r ) = @_; 2 * pi * ($r**2); }