in reply to Re: Simple add and multiply subroutines
in thread Simple add and multiply subroutines

Your equal sub has a painful concession to a special case. The value presented for 0 equaling 0 is false. I prefer it to be true, although then the concession is that the return is no longer the value from the call.

BTW, if you're really wanting to cut down on duplicated code and don't mind torturing the language a bit, you can do this:

#!/usr/bin/perl -- use strict; use warnings; my $op = shift @ARGV; my $minmax = '$result ? $_[0] : $_[1];'; my $settruth = '$result ? 1 : 0;'; my %ops = ( 'add' => { 'op' => '+' }, 'multiply' => { 'op' => '*' }, 'subtract' => { 'op' => '-' }, 'divide' => { 'op' => '/' }, 'lesser' => { 'op' => '<' }, 'greater' => { 'op' => '>' }, 'power' => { 'op' => '**' }, 'xor' => { 'op' => '&&', 'pre' => '$_[0] = ! $_[0];' }, 'all' => { 'op' => '&&', 'post' => $settruth }, 'none' => { 'op' => '||', 'post' => $settruth, 'last' => '$tot + = ! $tot; $tot += 0;' }, 'any' => { 'op' => '||', 'post' => $settruth }, 'min' => { 'op' => '<', 'post' => $minmax }, 'max' => { 'op' => '>', 'post' => $minmax }, 'mean' => { 'op' => '+', 'last' => '$tot /= scalar (@_ + 1);' + }, 'geomean' => { 'op' => '*', 'last' => '$tot = $tot ** ( 1 / scal +ar (@_ + 1) );' }, 'equal' => { 'op' => '-', 'post' => '$result = $result ? 0 : $ +_[1];', 'last' => 'local $" = "||"; $tot = 1 if 0 == $tot && 0 == eval + "@_";'} ); sub make_op { my $op = shift; my $result = 0; $ops{$op}{'sub'} = sub { ( eval $ops{$op}{'pre'} ) if defined $ops{$op}{'pre'}; $result = ( eval $_[0] . $ops{$op}{'op'} . $_[1] ) + 0; $result = ( eval $ops{$op}{'post'} ) if defined $ops{$op}{'pos +t'}; return $result; }; } sub do_op { my $op = shift; my $tot = shift; make_op( $op ) unless ( exists $ops{$op}{'sub'} && defined $ops{$op}{'sub'} && ref $ops{$op}{'sub'} eq 'CODE' ); foreach ( @_ ) { $tot = $ops{$op}{'sub'}( $tot, $_ ); } if ( exists $ops{$op}{'last'} ) { eval $ops{$op}{'last'}; } return $tot; } printf "%-0.03f\n", do_op( $op, @ARGV );

I know, I know... It's ugly to do from 1 to 3 evals for each iteration and possibly another one or two at the end. The data structures could have clearer names. At least only the op you need gets its sub created. I did say the language would be tortured a bit, didn't I? It's kind of a fun little toy, though.