3

Here is what I have:

operator = '>'

Here is what I tried:

5 operator.to_sym 4

#invalid result => 
5 :>= 4 

Expected: 5 > 4

Prashanth Sams
  • 19,677
  • 20
  • 102
  • 125

2 Answers2

8

You can use public_send or (send depending the method):

operator = :>
5.public_send(operator, 4)
# true

public_send (as send) can receive a method as String or Symbol.

In case the method you're using isn't defined in the object class, Ruby will raise a NoMethodError.


You can also do receiver.method(method_name).call(argument), but that's just more typing:

5.method(operator).call(4)
# true

Thanks @tadman for the benchmark comparing send and method(...).call:

require 'benchmark'

Benchmark.bm do |bm|
  repeat = 10000000

  bm.report('send')        { repeat.times { 5.send(:>, 2) } }
  bm.report('method.call') { repeat.times { 5.method(:>).call(2) } }
end

#              user       system     total    real
# send         0.640115   0.000992   0.641107 (  0.642627)
# method.call  2.629482   0.007149   2.636631 (  2.644439)
Sebastián Palma
  • 32,692
  • 6
  • 40
  • 59
  • `send` is the recommended method. The `method` approach is [about 5x slower](https://gist.github.com/tadman/ed6bf2f9e9b2bb68a8818cc52075495e) but is useful in other situations where `send` isn't practical. – tadman Oct 15 '19 at 16:30
3

Check out Ruby string to operator - you need to use public send:

operator = '>'
5.public_send(operator, 4)
=> true
operator = '-'
5.public_send(operator, 4)
=> 1
Mark
  • 6,112
  • 4
  • 21
  • 46