You can declare and initialize $sum in one line. my $sum = 0;
If you shift the operation off of @ARGV, you can then use the more natural notation for calling the subs:
my $op = shift @ARGV; if ( $op eq 'add' ) { my $rtn = add( @ARGV ); print "The sum is: $rtn\n"; } elsif ( $op eq 'multiply' ) { my $rtn = multiply( @ARGV ); print "The product is: $rtn\n"; }
Some people place the else or elsif on the same line as the right curly bracket, and some place it on the next. I'm not sure you'll ever see someone skip a line between an if and an else/elsif entirely, and that's probably a good thing.
Although Perl is only in rare cases sensitive to the presence or absence of white space, it helps readability of your code if you use a space between disparate tokens.
That could also, since you have a single line in your foreach loop, easily be written this way:sub add { my $sum = 0; for ( @_ ) { $sum += $_; } return $sum; }
sub add { my $sum = 0; $sum += $_ for @_; return $sum; }
Some people frown upon looping and conditional modifiers at the end of a line, but other find the notation quite handy. It is nice and compact.
A for loop and a foreach loop are the same thing. There was a widespread habit once upon a time of using "for" only with a C-style set, check, update style loop and using "foreach" for iterating over a list. Many people just use "for" in both cases, but if you're working under a professor or with a group of other programmers who tend to use "foreach", then it's probably a good idea to follow your local convention.
Another solution to your problem, in which the main program is very short, is this:
#!/usr/bin/perl -- use strict; use warnings; my $op = shift @ARGV; my %ops = ( 'add' => sub { my $s = 0; $s += $_ for @_; print "The sum is: $s\n +" }, 'multiply' => sub { my $p = 1; $p *= $_ for @_; print "The product + is: $p\n" } ); $ops{$op}(@ARGV) if exists $ops{$op};
That last one uses something called a dispatch table. The subroutines are a bit longer even than yours (although I've compacted them vertically here), but the logic of the main program has been made very simple by indexing into the table based on the operator. By moving everything concerned with the type of operation being performed into the sub, the main program doesn't have to have any logic beyond seeing if a sub exists to process a certain operation.
Other options of course exist. One that you'd likely catch all kinds of crap from a professor (or anyone interested in maintainability, likely) is this:
#!/usr/bin/perl -- use strict; use warnings; my $op = shift @ARGV; my $result; $op eq 'add' ? ( $result = 0, map { $result += $_ } @ARGV ) : ( $result = 1, map { $result *= $_ } @ARGV ); print ( $op eq 'add' ? 'The sum is:' : 'The product is:' ); print " $result\n";
I recommend against using that one, unless you have a professor who grades highly for unusual implementations or you're looking to convince a coworker to steer wide of your code. The map in particular is troubling, since it's being used as a loop in a void context. The program also makes two tests against one condition, and does not continue testing for 'multiply' in the else clauses.
In reply to Re: Simple add and multiply subroutines
by mr_mischief
in thread Simple add and multiply subroutines
by negzero7
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |