oldhomemovie
oldhomemovie

Reputation: 15129

A bit complicated eval in Ruby

I need a special behavior from eval, to evaluate strings like:

'5a + 6b + 3a + 11b'

into

'8a + 17b'

Is it possible? If it is, can you give a proper example? I found this example recently, where the talk was about evaluating strings with meters and inches.

Upvotes: 1

Views: 460

Answers (3)

sepp2k
sepp2k

Reputation: 370162

The way it is written, that's not valid ruby syntax, so it can't be evaled.

You have two options:

a) Don't use eval. I would think that this is the best option, but I supposed that depends on the context.

b) Change the syntax to 5.a + 6.b + 3.a + 11.b and define appropriate a and b methods, like so:

class Expr
  attr_accessor :a,:b
  def initialize(a,b)
    @a, @b = a,b
  end

  def +(other)
    Expr.new(a + other.a, b + other.b)
  end

  def inspect
    "<expr: #{a}a + #{b}b>"
  end
end

class Numeric
  def a
    Expr.new(self, 0)
  end

  def b
    Expr.new(0, self)
  end
end

5.a + 6.b + 3.a + 11.b #=> <expr: 8a + 17b>

Upvotes: 4

khelll
khelll

Reputation: 24000

Well, the problem here is not related to Ruby's eval. You need a simple interpreter (parser+evaluator) to interpret the above mentioned expressions. There are some solutions for your problem but you need to give a proper explanation for the syntax you are trying to parse.

For example in your case I would do something like this:

res = ['a','b'].map do |sym| 
  '5a + 6b + 3a + 11b'.scan(/(\d+)#{sym}/).flatten.inject(0){|sum,x| sum + x.to_i}.to_s + sym
end.join(" + ")
puts res #=> 8a + 17b

Upvotes: 2

Roman
Roman

Reputation: 349

I guess depending on your problem this might be very complex. I do not know a library for mathematical optimization in ruby. I fear it is not possible with ruby eval. But you probably could write your own optimizer. If you think of the expression that way:

  • +
    • *
      • 5
      • a
    • *
      • 6
      • b
    • *
      • 3
      • a
    • *
      • 11
      • b

You can group summands with equal variable, summarize the numbers and create a new expression string. For the parsing Treetop could be worth a look.

Upvotes: 1

Related Questions