send和instance_eval之间的Ruby差异?

问题描述 投票:6回答:2

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

我的问题是下面的例子中“引擎盖下”的区别是什么?

1234.send 'to_s'               # '1234'
1234.instance_eval 'to_s'      # '1234'
ruby send instance-eval
2个回答
7
投票

来自fine manual

发送(符号[,args ...])→obj send(string [,args ...])→obj

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

并为instance_eval

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

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

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

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

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


7
投票

无论你用send做什么都是instance_eval的一个合适的子集。也就是说,send的参数必须是单个方法(及其参数),而instance_method的参数是任意代码。因此,每当你有send时,你可以用instance_eval重写它,但反之亦然。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.