send和instance_eval之间的Ruby区别?
Posted
技术标签:
【中文标题】send和instance_eval之间的Ruby区别?【英文标题】:Ruby difference between send and instance_eval? 【发布时间】:2013-08-05 12:21:41 【问题描述】:我知道 send 接受带有参数的字符串或符号,而 instance_eval 接受字符串或块,并且在给定接收器的情况下,它们的区别可能很明显。
我的问题是以下示例的“幕后”区别是什么?
1234.send 'to_s' # '1234'
1234.instance_eval 'to_s' # '1234'
【问题讨论】:
【参考方案1】:来自fine manual:
send(symbol [, args...]) → objsend(string [, args...]) → obj
调用由 symbol 标识的方法,将任何指定的参数传递给它。 [...] 当方法由字符串标识时,字符串被转换为符号。
对于instance_eval
:
instance_eval(string [, filename [, lineno]] ) → objinstance_eval | |块 → obj
在接收器 (obj) 的上下文中评估包含 Ruby 源代码或给定块的字符串。为了设置上下文,变量
self
在代码执行时被设置为obj,让代码可以访问obj的实例变量。
所以send
执行一个方法,而instance_eval
执行任意代码块(作为字符串或块),其中self
设置为您正在调用instance_eval
的对象。
在您的情况下,没有太大区别,因为您传递给 instance_eval
的字符串只是一个方法。主要区别在于,任何阅读您的代码的人(包括六个月后的您)都会想知道为什么您使用instance_eval
来调用单个方法。
您可能还对Object#public_send
和BasicObject#__send__
感兴趣
【讨论】:
太好了,我已经想知道为什么我有一个instance_eval
的单一方法。【参考方案2】:
你可以用send
做的任何事情都是instance_eval
的一个真子集。也就是说,send
的参数必须是单个方法(及其参数),而instance_method
的参数是任意代码。所以只要你有send
,你就可以用instance_eval
重写它,反之则不行。
但是,在性能方面,send
比 instance_eval
快得多,因为执行 send
不需要额外的解析,而 instance_eval
需要解析整个参数。
在您的示例中,结果将是相同的,但第一个会运行得更快。
【讨论】:
以上是关于send和instance_eval之间的Ruby区别?的主要内容,如果未能解决你的问题,请参考以下文章