Ruby:使用变量的动态绑定(bind)评估字符串

标签 ruby

我有一个存储为字符串的“公式”数据库。为简单起见,我们假设每个公式包含 2 个变量,分别用 a 和 b 表示,并且这些公式都是格式正确的,并且确保它只包含集合 ()ab+-* 中的字符。

在运行时,从该数据库中获取公式,并从另一个来源获取 a 和 b 的数值,并对公式求值。评估可以像这样编程:

# This is how it works right now
formula = fetch_formula(....)
a = fetch_left_arg(....)
b = fetch_right_arg(....)
result = eval(formula)

这个设计可行,但我并不完全满意。它要求我的程序命名自由变量与它们在公式中的命名完全相同,这很丑陋。

如果我的“公式”不是字符串,而是接受两个参数的 Proc 对象或 Lambda,我可以做类似的事情

# No explicitly named variables
result = fetch_proc(...).call(fetch_left_arg(....),fetch_right_arg(....))

但不幸的是,公式必须是字符串。

我尝试以下列方式进行实验:如果从数据库中获取公式的方法将字符串包装成某种东西,其行为类似于 block ,并且我可以将参数传递给它,那会怎么样?

# This does not work of course, but maybe you get the idea:
block_string = "|a,b| #{fetch_formula(....)}"

当然我不能评估这样一个block_string,但是有没有类似的东西我可以使用?我知道 instance_eval 可以传递参数,但我应该将它应用于什么对象?所以这也许也不是一个选择....

最佳答案

这是非常讨厌的方法,但对于您提到的简单公式,它应该有效:

▶ formula = 'a + b'
▶ vars = formula.scan(/[a-z]+/).uniq.join(',')  # getting vars names
#⇒ "a,b"
▶ pr = eval("proc { |#{vars}| #{formula} }") # preparing proc
▶ pr.call 3, 5
#⇒ 8

这里我们依赖于这样一个事实,即参数以相同的顺序传递给 proc,因为它们出现在公式中。

关于Ruby:使用变量的动态绑定(bind)评估字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35274367/

相关文章:

ruby - 使用 'first_or_create' 时应该如何合并哈希

ruby-on-rails - Rails add_index 算法 : :concurrently still causes database lock up during migration

ruby-on-rails - 如果子数据不存在,如何获取父数据

ruby-on-rails - 当每个用户在 Rails 应用程序中注册时,为他们分配一个随机数

ruby - 如何从 Ruby BigDecimal 对象获取精度(小数点后的位数)?

python - 什么是 Ruby 等价于 Python 的 `s= "你好,%s。 %s 在哪里 ?"% ("John","Mary")`

ruby - Rails 3.2.6 路线不再有效

ruby - 使用 excel vlookup 等键值对将键数组连接到哈希

ruby-on-rails - 无法在 ruby​​ rspec 中解析哈希

ruby - {}之间是什么?