好的,通过link查看Procs,lambdas和block。
关于此代码的问题:
class Array
def iterate!
self.each_with_index do |n, i|
self[i] = yield(n)
end
end
end
array = [1, 2, 3, 4]
array.iterate! do |n|
n ** 2
end
puts array.inspect
从概念上讲,我几乎了解所有事情,除了一行:
self[i] = yield(n)
我认为这一行中的自我self.each_with_index do |n, i|
意味着它是一种类方法,对吧?
但为什么我们需要将yield(n)
中的参数分配给self[i]
?
如果可以的话,请以超级基本的方式解释。
(换句话说,请保持友善 - 这里的人通常都是大多数人 - 只是有点紧张,以至于我没有得到这让我觉得愚蠢的事情)
答案 0 :(得分:0)
方法是iterate!
,这是一种实例方法。 self
中的self.each_with_index
是方法Enumerable#each_with_instance的接收者。由于self
是Array
(示例中为[1,2,3,4]
)的当前实例,因此不需要self.
;也就是说,你可以(和imo,应该)只写each_with_index do |n, i|...
。换句话说,self
是未指定显式接收器时的隐含接收器。
关于这一行:
self[i] = yield(n)
您的示例array = [1,2,3,4]
您的枚举器是:
enum = [1,2,3,4].each_with_index
#=> #<Enumerator: [1, 2, 3, 4]:each_with_index>
包含元素
enum.to_a
#=> [[1, 0], [2, 1], [3, 2], [4, 3]]
Array#each
传递给块的第一个元素因此是[1,0]
,它被分配给块变量:
n = 1
i = 0
导致
self[0] = yield(1) => 1**2 => 1
等等。
答案 1 :(得分:0)
我会尝试以超级基本的方式解释。
我认为这一行
self.each_with_index do |n, i|
意味着这个自我 这是一种课堂方法,对吗?
不。 self
的含义取决于上下文。如果self
在类中,它将引用该类。但是这里self
在实例方法中,所以它引用了实例(所以each_with_index
也是一个实例方法)。
但为什么我们需要将
yield(n)
中的参数分配给self[i]
?
iterate!
的目标是修改数组。由于self
引用实例,self[i]
访问正在调用iterate!
的数组元素,从而修改数组。
另外,我不确定你的意思&#34;参数&#34;这里。 yield(n)
将n
传递给块,运行块,然后返回值。
答案 2 :(得分:0)
self[i] = yield(n)
将数组中的值重新分配给
array.iterate! do |n|
n ** 2
end
这基本上意味着,取数组的值,并将其平方,将该值保存在数组的元素中。因此[1, 2, 3 , 4]
变为[1 ** 2, 2 ** 2, 3 ** 2, 4 ** 2] => [2, 4, 9, 16]
答案 3 :(得分:0)
自我改变(实际上是)当前上下文或周围对象。
由于
self.each_with_index do |n, i|
...
是猴子修补Array类并且在实例方法iterate!
中,self指的是实例本身:在这种情况下是数组[1, 2, 3, 4]
。
您可能正在考虑这个问题:
class some_class
def self.a_class_method
...
在类的上下文中定义。所以self是类本身(也是一个对象),而不是该类的实例。
因为self只是数组[1, 2, 3, 4]
self[i] = yield(n)
正在用块中发送的结果替换数组的每个元素。
答案 4 :(得分:0)
这里迭代!是Array类的实例函数,你有一个数组对象。当你做
array.iterate! do |n|
n ** 2
end
你正在传递一个块'do | n | n ** 2结束'迭代! function。在函数中,您可以使用yield访问此块。但是您可以看到块期望通过| n |获得一个参数所以你需要传递一个参数,块代码将返回它的平方。
self[i] = yield(n)
self正在Array实例context中使用。所以它正在修改数组的值。
有关详细信息,请查看此文章: