处理基于Ruby的应用程序时需要在以后创建,存储和评估自定义公式。例如,我可能有:存储具有特定值的公式的最佳方法
10 * (2 + number_of_pies_eaten)
其中number_of_pies_eaten
目前未知,并且当它被评估将被代入公式。
除了编写我自己的插值解释程序之外,是否有一种最佳实践方式来做这种事情?
处理基于Ruby的应用程序时需要在以后创建,存储和评估自定义公式。例如,我可能有:存储具有特定值的公式的最佳方法
10 * (2 + number_of_pies_eaten)
其中number_of_pies_eaten
目前未知,并且当它被评估将被代入公式。
除了编写我自己的插值解释程序之外,是否有一种最佳实践方式来做这种事情?
当我想创建一个类来解决函数Riemann sum的问题时,我遇到了类似的问题。
在这种情况下,我用特效:
f = ->(x) { -10*(x**2) + 3*x + 6 }
我会说,这取决于具体的实现。实际上,你可以:
定义一个包含一个class
一些公式,通过你在构造函数中number_of_pies_eaten
,做一些
class PieEater
def initialize(number_of_pies_eaten)
@eaten_pies = number_of_pies_eaten
end
def something
@something = 10 * (2 + @eaten_pies)
end
def something_else
@something_else = 5 * (3 + @eaten_pies)
end
end
用法:
pe = PieEater.new(15)
pe.do_something
pe.do_something_else
定义一个包含一些公式一module
将其纳入另一个班级。
module PieEater
def something(x)
10 * (2 + x)
end
def something_else(x)
5 * (3 + x)
end
end
用法:
require 'pie_eater'
class Person
include PieEater
end
p = Person.new
p.something(15)
创建module
或class
含有一些公式马上使用。
module PieEater
extend self
def something(x)
10 * (2 + x)
end
def something_else(x)
5 * (3 + x)
end
end
或
class PieEater
class << self
def something(x)
10 * (2 + x)
end
def something_else(x)
5 * (3 + x)
end
end
end
用法:
PieEater.something(15)
如果你正在写某种剧本,我会用进程内对象:
$ irb
2.4.0 :001 > eaten_pies = ->(n) { 10 * (2 + n) }
=> #<Proc:[email protected](irb):1 (lambda)>
2.4.0 :002 > eaten_pies.call(2)
=> 40
# You could even use these procs as hash values
2.4.0 :003 > formulas = { a: eaten_pies, b: ->(x){ x**2 } }
=> {:a=>#<Proc:[email protected](irb):1 (lambda)>, :b=>#<Proc:[email protected](irb):4 (lambda)>}
2.4.0 :004 > formulas[:a].call(15)
=> 170
2.4.0 :005 > formulas[:b].call(15)
=> 225
这可以写成:
formulas = {
eaten_pies: ->(x) { 10 * (2 + n) },
eaten_apples: ->(y) { y ** 2 }
}
formulas[:eaten_pies].call(15)
所有这些可能性是在Ruby中的标准,它取决于你的使用情况和您的编码风格
这些解决方案的问题是它们不允许在前端*上动态创建公式*。基本上,应用程序的用户可以自由使用我创建的公式生成器接口,以基于他们也创建的数据片段生成他们自己的公式。举个更具体的例子:用户创建一个表单,要求“饼数”和“蛋糕数”,然后他们建立一个公式,可能会说''({number_of_pies} + {number_of_cakes})* 5 ''' –
对于迟到的回复也很抱歉,我忘了在这里检查! –
你有没有考虑存储序列化特效的DB? – hoffm
当然,这是最后的手段。如果您能够限制公式中的变化种类,您应该能够为它们找到更加结构化的数据模型。 – hoffm
最简单的方法是将其存储为字符串,然后使用eval()来执行。问题是不评估危险代码;) –