【问题标题】:ruby eval metaprogramming trickruby eval 元编程技巧
【发布时间】:2013-07-19 07:38:09
【问题描述】:

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

具体来说,我有一个字符串类型的函数 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 需要一个参数这一事实。当要发送的参数必须带参数时,我不知道如何调用 send(或 try)
  • 我的另一个想法是重写 Time 类,向它添加一个转换函数,如 to_s,但这不需要任何参数。

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

感谢任何反馈。

谢谢

【问题讨论】:

  • 你在哪个命名空间下创建了display_datetime
  • 在ApplicationHelper下
  • 抱歉没有回复帖子。这不知何故从雷达上消失了。我现在就回复。

标签: ruby-on-rails ruby metaprogramming eval


【解决方案1】:

send 没有问题。这样做:

send(x, y)

【讨论】:

  • 这行得通。您只需要在对象上调用 send 即可。所以我接受这个答案。我不知道 send 可以使用函数名和参数列表。我验证了如果 y 是 fixnum 类型,那么函数内部的类型仍然是 fix num。所以没有发生字符串转换。这使它成为满足我需求的最佳方法。
【解决方案2】:

给定

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

还有一些响应display_datetime()方法的对象o,你可以通过多种方式动态调用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)"))

【讨论】:

  • 感谢您的回答。您的第一个解决方案对我来说效果很好。最后 3 个不起作用,因为 y 在所有这些中都被字符串化了。不过我把答案告诉了另一个人,因为他来得早。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多