1

我试图找到一种方法来评估由函数和参数组成的表达式。问题是,我不希望将参数转换为字符串。

具体来说,我有一个字符串类型的函数 x="display_datetime",它接受一个时间类型的对象 y。函数名是动态创建的,所以我不能只键入 display_datetime(y)。

我试过的:

  • eval("#{x}(#{y})") - 这是我通常的做法,但这会将 Time 转换为字符串。“display_datetime”的全部目的是进行自定义时间到字符串的转换,所以这没有用

  • x.send(y) - 这不会编译,因为 send 旨在发送类函数,而不是函数参数。

  • x.constantize ... - 也不会编译,即使 x 包含类名。

  • y.send(:to_s(:datetime))这种方法不太理想,但我仍然无法让它发挥作用。display_datetime 只是调用 y.to_s(:datetime),所以我尝试将动态生成的函数名称 x 简单地设置为 .to_s(:datetime),然后使用 send 命令在 y 上调用 x。这会起作用,除了 to_s 需要一个参数这一事实。当要发送的参数必须带参数时,我不知道如何调用发送(或尝试)
  • 我的另一个想法是重写 Time 类,为它添加一个转换函数,如 to_s,但这不需要任何参数。

最后两种方法不太理想。我觉得必须有一些更好的方法来按照前 3 种方法做到这一点。

任何反馈表示赞赏。

谢谢

4

2 回答 2

3

没有问题send。做这个:

send(x, y)
于 2013-07-19T07:41:59.880 回答
2

给定

s = "display_datetime" # function name, dynamic
y = Time.now           # or some other Time object

而一些o响应display_datetime()方法的对象,你可以o.display_datetime通过多种方式动态调用,至少:

o.send(s.intern, y)    # => o.send(:display_datetime, y)

或者,

eval("o.#{s}(y)")      # => eval("o.display_datetime(y)")

或者,

o.instance_eval("#{s}(y)") # => o.instance_eval("display_datetime(y)")

或者如果你想要evalception,如果变量n包含变量的名称o

n = 'o'
eval %Q(#{n}.send(:instance_eval, "\#{s}(y)"))
于 2013-07-19T10:05:38.790 回答