Vicky
Vicky

Reputation: 489

Best way to execute math expression string in ruby?

I want to execute math expression which is in string like this sample strings:

  1. A = "23>=34"
  2. B = "77<90"
  3. C = "33>77"

and I want some function like if exec_string(A) which should return true or false.

Currently I am using this method:

    rest = --- # I am splitting the string in to three(L- as left number cmpr- as compare and R- as right number )
    class_name.calc(rest[0],rest[1],rest[2])
    def self.calc(L,cmpr,R)
        case cmpr
          when "<"
            if L.to_i < R.to_i
              return true
            end
           ....
           ....
           ....
         end
    end 

Which could not handle lot of cases. Any help?

Upvotes: 2

Views: 3595

Answers (3)

spickermann
spickermann

Reputation: 106882

You can use eval for that:

eval("23>=34")
#=> false

eval("23<=34")
#=> true

Warning: Keep in mind that using eval is dangerous. Especially when the evaluated string is provided by a user. Imagine what happens if the user passes a command to delete files, instead of a simple number comparison.

Upvotes: 6

schwabsauce
schwabsauce

Reputation: 447

I'm going to try combining eval with a regular expression that ensures no letters are present (/[\d\.\+\s]+/ for example, since my only needed operation is addition). That way with just numbers and operators, no classes can be instantiated or non-numeric methods invoked.

Upvotes: 0

rohit89
rohit89

Reputation: 5773

You can use Object#send to do this

Invokes the method identified by symbol, passing it any arguments specified.

def self.calc(L, cmpr, R)      
    left = L.to_i
    right = R.to_i
    operator = cmpr.to_sym
    left.send(operator, right)
end 

For example,

irb(main):001:0> 5.send(:+, 7)
=> 12
irb(main):002:0> 3.send(:>=, 5)
=> false
irb(main):003:0> 5.send(:>=, 2)
=> true
irb(main):004:0> 12.send(:-, 3)
=> 9

Upvotes: 1

Related Questions