處理基於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()來執行。問題是不評估危險代碼;) –