in reply to eval question

Sure!  Just use a dispatch table ...
#!/usr/bin/perl -w use strict; use warnings; my $p_operations = { '+' => sub { $_[0] + $_[1] }, '-' => sub { $_[0] - $_[1] }, '*' => sub { $_[0] * $_[1] }, '/' => sub { $_[0] / $_[1] }, }; # Get operation $op, and values $x and $x in whatever fashion # ... # For testing my $x = 12; my $y = 7; my $op = "*"; my $result = $p_operations->{$op}->($x, $y); print "The result of $x $op $y is: $result\n";

s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

Replies are listed 'Best First'.
Re^2: eval question
by jdrago_999 (Hermit) on Apr 16, 2007 at 14:58 UTC
    I second your suggestion. Parse::RecDescent would work for this (recently figured that one out too) but in this case, the above example will work well for simple calculations.

    However - what if you need to do something that involves precedence? i.e. -
    1 + 9 * ( 60 / 5 )

    What is the recommended path there?
      I'll confess that I haven't used Parse::RecDescent ... a need for it hasn't yet arisen.

      If you were doing something complicated (eg. your precedence problem), my first inclination would be to use eval, but only after validating that the input was sane.  For example:

      #!/usr/bin/perl -w use strict; use warnings; # Test data my $string = "1 + 9 * ( 60 / 5 )"; # Validate if ($string !~ m:^[-+*/()0-9.\s]+$:) { die "Bad input '$string'\n"; } my $result = eval $string; print "Result of '$string' = $result\n";

      But I don't know offhand if that's the best way to do it, or what other caveats you might run into.

      Update:  Fixed the regexp.


      s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re^2: eval question
by Anonymous Monk on Apr 17, 2007 at 04:48 UTC
    Dispatch table is so cool. And it's a good substitute of 'switch'. But when perl 6 come out (built-in switch), it will be useless.May be I'm wrong.
      I've used dispatch tables in C, even though it has a switch statement. The advantage of dispatch tables is that you don't have to repeat the code the lists the args and you don't have to repeat the code that stores the return value.
      my @callbacks = ( &some_handler, &another_handler, &foo_handler, &bar_handler, ); my $rv = $callbacks[$event]->($arg0, $arg1);

      vs

      my $rv; given ($event) { when SOME_EVENT { $rv = some_handler ($arg0, $arg1); } when ANOTHER_EVENT { $rv = another_handler($arg0, $arg1); } when FOO_EVENT { $rv = foo_handler ($arg0, $arg1); } when BAR_EVENT { $rv = bar_handler ($arg0, $arg1); } };

      Arrays of function procs are also useful when the entire list needs to be executed.

      foreach (@procs) { $_->(); }