2

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?

1
  • Some users will say that this is bad practice, but you might want to look into eval and bindings. Perhaps someone with more experience with these functions could comment on whether they're bad practice and why. Commented Nov 5, 2015 at 11:03

3 Answers 3

6

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.

Sign up to request clarification or add additional context in comments.

2 Comments

You should specifically mention that eval runs any ruby code, including those simple expressions, that's why it can be dangerous
Interesting how this question came up... Similarly, I've been wondering how to solve systems of equations in Ruby. Would a similar eval process work?
1

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

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.