[英]Ruby difference between send and instance_eval?
I know send takes string or symbol with arguments while instance_eval takes string or block, and their difference could be apparent given receivers. 我知道send接受带有参数的字符串或符号,而instance_eval接受字符串或块,并且给定接收器它们的区别可能很明显。
My question is what the ' under the hood ' difference is for the example below? 我的问题是下面的例子中“引擎盖下 ”的区别是什么?
1234.send 'to_s' # '1234'
1234.instance_eval 'to_s' # '1234'
From the fine manual : 从精细手册 :
send(symbol [, args...]) → obj
发送(符号[,args ...])→obj
send(string [, args...]) → objsend(string [,args ...])→obj
Invokes the method identified by symbol , passing it any arguments specified.
调用由symbol标识的方法,并将指定的任何参数传递给它。 [...] When the method is identified by a string, the string is converted to a symbol.
[...]当通过字符串标识方法时,字符串将转换为符号。
and for instance_eval
: 和
instance_eval
:
instance_eval(string [, filename [, lineno]] ) → obj
instance_eval(string [,filename [,lineno]])→obj
instance_eval {|instance_eval {| |
| block } → obj
block}→obj
Evaluates a string containing Ruby source code, or the given block, within the context of the receiver ( obj ).
在接收器( obj )的上下文中计算包含Ruby源代码或给定块的字符串。 In order to set the context, the variable
self
is set to obj while the code is executing, giving the code access to obj ’s instance variables.为了设置上下文,在代码执行时将变量
self
设置为obj ,使代码可以访问obj的实例变量。
So send
executes a method whereas instance_eval
executes an arbitrary block of code (as a string or block) with self
set to the object that you're calling instance_eval
on. 因此
send
执行一个方法,而instance_eval
执行任意代码块(作为字符串或块),并将self
设置为您正在调用instance_eval
的对象。
In your case, there isn't much difference as the string you're handing to instance_eval
is just a single method. 在您的情况下,没有太大的区别,因为您要处理的字符串
instance_eval
只是一个方法。 The main difference is that anyone reading your code (including you in six months) will be wondering why you're using instance_eval
to call a single method. 主要区别在于,任何阅读代码的人(包括六个月内的代码)都会想知道为什么要使用
instance_eval
来调用单个方法。
You might also be interested in Object#public_send
and BasicObject#__send__
您可能也对
Object#public_send
和BasicObject#__send__
Whatever you can do with send
is a proper subset of that of instance_eval
. 无论你使用
send
做什么都是instance_eval
的适当子集。 Namely, the argument to send
has to be a single method (and its arguments), whereas the argument to instance_method
is an arbitrary code. 也就是说,
send
的参数必须是单个方法(及其参数),而instance_method
的参数是任意代码。 So whenever you have send
, you can rewrite it with instance_eval
, but not vice versa. 因此,无论何时
send
,都可以使用instance_eval
重写它,但反之亦然。
However, performancewise, send
is much faster than instance_eval
since there is no additional parsing required to execute send
, whereas instance_eval
needs to parse the whole argument. 但是,在性能方面,
send
比instance_eval
快得多,因为执行send
不需要额外的解析,而instance_eval
需要解析整个参数。
In your example, the result will be the same, but the first one will run faster. 在您的示例中,结果将是相同的,但第一个将运行得更快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.