【问题标题】:Ruby difference between send and instance_eval?send和instance_eval之间的Ruby区别?
【发布时间】:2013-08-05 12:21:41
【问题描述】:

我知道 send 接受带有参数的字符串或符号,而 instance_eval 接受字符串或块,并且在给定接收器的情况下,它们的区别可能很明显。

我的问题是以下示例的“幕后”区别是什么?

1234.send 'to_s'               # '1234'
1234.instance_eval 'to_s'      # '1234'

【问题讨论】:

    标签: ruby send instance-eval


    【解决方案1】:

    来自fine manual

    send(symbol [, args...]) → obj
    send(string [, args...]) → obj

    调用由 symbol 标识的方法,将任何指定的参数传递给它。 [...] 当方法由字符串标识时,字符串被转换为符号。

    对于instance_eval

    instance_eval(string [, filename [, lineno]] ) → obj
    instance_eval {| |块 } → obj

    在接收器 (obj) 的上下文中评估包含 Ruby 源代码或给定块的字符串。为了设置上下文,变量self在代码执行时被设置为obj,让代码可以访问obj的实例变量。

    所以send 执行一个方法,而instance_eval 执行任意代码块(作为字符串或块),其中self 设置为您正在调用instance_eval 的对象。

    在您的情况下,没有太大区别,因为您传递给 instance_eval 的字符串只是一个方法。主要区别在于,任何阅读您的代码的人(包括六个月后的您)都会想知道为什么您使用instance_eval 来调用单个方法。

    您可能还对Object#public_sendBasicObject#__send__ 感兴趣

    【讨论】:

    • 太好了,我已经想知道为什么我有一个 instance_eval 的单一方法。
    【解决方案2】:

    你可以用send 做的任何事情都是instance_eval 的一个真子集。也就是说,send 的参数必须是单个方法(及其参数),而instance_method 的参数是任意代码。所以只要你有send,你就可以用instance_eval重写它,反之则不行。

    但是,在性能方面,sendinstance_eval 快得多,因为执行 send 不需要额外的解析,而 instance_eval 需要解析整个参数。

    在您的示例中,结果将是相同的,但第一个会运行得更快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-28
      • 2013-05-26
      • 2012-05-21
      • 1970-01-01
      • 1970-01-01
      • 2010-12-19
      • 2014-10-31
      相关资源
      最近更新 更多