ruby eval元编程技巧

时间:2013-07-19 07:38:09

标签: ruby-on-rails ruby metaprogramming eval

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

具体来说,我有x =" display_datetime" String类型,它采用Time类型的对象y。函数名是动态创建的,所以我不能只键入display_datetime(y)。

我尝试过的事情:

  • eval("#{x}(#{y})") - 这就是我通常会这样做的方式,但这会改变字符串的时间。 " 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接受一个参数这个事实。当发送的参数必须参与争论时,我不知道如何调用send(或try)
  • 我的另一个想法是覆盖Time类,为to_s添加一个转换函数,但这不会引起任何争论。

最后两种方法并不理想。我觉得必须有更好的方法来实现前三种方法。

感谢任何反馈。

由于

2 个答案:

答案 0 :(得分:3)

send没有问题。这样做:

send(x, y)

答案 1 :(得分: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)"))