in reply to '+' to +

#!perl use warnings; use strict; my %arith; $arith{"+"} = sub { $_[0] + $_[1] }; $arith{"-"} = sub { $_[0] - $_[1] }; $arith{"*"} = sub { $_[0] * $_[1] }; $arith{"/"} = sub { $_[0] / $_[1] }; my $Problem = "6 * 8"; $Problem =~ /^(\d*)\s(.)\s(\d*)$/; my $Number1 = $1; my $Number2 = $3; my $Operator = $2; my $Op = $arith{$2} or die qq[wrong operator: "$Operator"]; my $Answer; $Answer = &$Op($Number1, $Number2); print $Answer, "\n"; __END__

And take care with division by zero errors.

Replies are listed 'Best First'.
Re^2: '+' to +
by davido (Cardinal) on May 29, 2005 at 16:19 UTC

    I really like this solution, and decided to play around with it a little. Here it is with a little enhancement...

    use warnings; use strict; my %arith; $arith{"+"} = sub { $_[0] + $_[1] }; $arith{"-"} = sub { $_[0] - $_[1] }; $arith{"*"} = sub { $_[0] * $_[1] }; $arith{"/"} = sub { $_[0] / $_[1] }; my $problem = "6 + 1"; my $answer; if ( $problem =~ /^(\d+)\s*(\S)\s*(\d+)$/ and exists $arith{$2} ) { eval { $answer = $arith{$2}->( $1, $3 ); } } else { die "Oops!\nOperation syntax not understood.\n"; } die "Woops!\n$@" if $@; print "$answer\n";

    • Modified regexp to require two operands and to make whitespace optional.
    • Added basic validity/syntax checking to the results of the pattern match.
    • Trapped (and dealt with) possible errors resulting from mathematical operation using the block version of eval. Note, this is the safe version, we're not evaluating quoted text, we're evaluating known code to trap potential errors resulting from mathematical operation errors such as divide by zero.
    • Added more robust checking for the existance of a particular mathematical operator in the hashtable.
    • Switched to $funcref->(params) notation instead of &$funcref(params).

    It's a long way from being a full fledged algeraic expression parser, but it is a little more robust.


    Dave

Re^2: '+' to +
by ihb (Deacon) on May 29, 2005 at 16:37 UTC
Re^2: '+' to +
by NateTut (Deacon) on May 29, 2005 at 14:13 UTC
    Very Cool!