Ruby中有点复杂的eval

时间:2009-09-26 14:05:08

标签: ruby string eval

我需要来自eval的特殊行为,以评估字符串,如:

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

'8a + 17b'

有可能吗?如果是,你能给出一个正确的例子吗?我最近发现了this示例,其中的讨论是关于评估米和英寸的字符串。

3 个答案:

答案 0 :(得分:4)

它的编写方式,这不是有效的ruby语法,因此不能eval编辑。

您有两种选择:

a)不要使用eval。我认为这是最好的选择,但我认为这取决于上下文。

b)将语法更改为5.a + 6.b + 3.a + 11.b并定义适当的a和b方法,如下所示:

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>

答案 1 :(得分:2)

嗯,这里的问题与Ruby的eval无关。您需要一个简单的解释器(解析器+求值器)来解释上面提到的表达式。有一些解决方案可以解决您的问题,但您需要对要解析的语法给出正确的解释。

例如在你的情况下,我会做这样的事情:

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

答案 2 :(得分:1)

我想根据你的问题,这可能非常复杂。我不知道ruby中的数学优化库。我担心ruby eval是不可能的。但是你可能会编写自己的优化器。如果你想到这样的表达方式:

  • +
    • *
      • 5
      • 一个
    • *
      • 6
      • B'/ LI>
    • *
      • 3
      • 一个
    • *
      • 11
      • B'/ LI>

您可以使用相等的变量对summands进行分组,汇总数字并创建新的表达式字符串。对于解析Treetop可能值得一看。