我知道 send 接受带有参数的字符串或符号,而 instance_eval 接受字符串或块,并且在给定接收器的情况下,它们的区别可能很明显。
我的问题是以下示例的“引擎盖下”的区别是什么?
1234.send 'to_s' # '1234'
1234.instance_eval 'to_s' # '1234'
我知道 send 接受带有参数的字符串或符号,而 instance_eval 接受字符串或块,并且在给定接收器的情况下,它们的区别可能很明显。
我的问题是以下示例的“引擎盖下”的区别是什么?
1234.send 'to_s' # '1234'
1234.instance_eval 'to_s' # '1234'
来自精美手册:
发送(符号 [,args...])→ obj
发送(字符串 [,args...])→ obj调用由symbol标识的方法,将任何指定的参数传递给它。[...]当方法由字符串标识时,字符串被转换为符号。
instance_eval(string [, filename [, lineno]] ) → obj
instance_eval {| | 块 } → 对象在接收器 ( obj )的上下文中评估包含 Ruby 源代码或给定块的字符串。为了设置上下文,在代码执行时将变量
self
设置为obj,从而使代码可以访问obj的实例变量。
所以send
执行一个方法,同时instance_eval
执行任意代码块(作为字符串或块),并将其self
设置为您正在调用的对象instance_eval
。
在您的情况下,没有太大区别,因为您要处理的字符串instance_eval
只是一个方法。主要区别在于任何阅读您的代码的人(包括六个月后的您)都会想知道为什么您使用instance_eval
调用单个方法。
无论你能做什么send
都是instance_eval
. 也就是说, to 的参数send
必须是单个方法(及其参数),而 to 的参数instance_method
是任意代码。所以只要你有send
,你可以用 重写它instance_eval
,但反之则不行。
但是,从性能上讲,它比执行时不需要额外的解析send
要快得多,而需要解析整个参数。instance_eval
send
instance_eval
在您的示例中,结果将是相同的,但第一个会运行得更快。