array1 = [0, 1]
# CASE 1:
[array1].each do |arr|
arr = [3, 4]
end
=> [0, 1]
# CASE 2:
[array1].each do |arr|
arr.delete_if { |ele| ele == 0 }
end
=> [[1]]
我认为ruby总是通过引用传递数组。为什么不在CASE 1中更改数组的值,但在CASE 2中更改了它?感谢。
答案 0 :(得分:2)
在您的第一种情况下,您所做的就是更改哪个对象arr
指向 - 您实际上没有修改过原始对象。这可以通过以下脚本证明:
# Given our test value...
test_array = [1, 2]
# we can verify the values and the object_ids
puts "Value of `test_array`: #{test_array.inspect}"
puts "Object_id of `test_array`: #{test_array.object_id}"
# now, let's put it in a container and run it through a block
@array_container = [test_array]
@array_container.each do |arr|
# Just to prove that `arr` points at test_array
puts "Object_id of `arr`: #{arr.object_id}"
# and that it's the same as the first element in our container
puts "@container.first.object_id: #{@array_container.first.object_id}"
# but, when we re-assign our block variable
arr = [3, 4]
# we get different values
puts "Object_id of `arr`: #{arr.object_id}"
puts "@container.first.object_id: #{@array_container.first.object_id}"
end
哪些输出......
Value of `test_array`: [1, 2]
Object_id of `test_array` : 2150710260
Object_id of `arr` : 2150710260
@container.first.object_id: 2150710260
Object_id of `arr` : 2150708040
@container.first.object_id: 2150710260
那么案例2中的情况有何不同?在案例2中,您实际上是在调用自毁方法,该方法将对arr
答案 1 :(得分:0)
我认为你的问题与范围有关。 do-end
构造实际上是一个新块,因此当您声明arr = [3, 4]
时,您正在该块中实例化一个新的arr = [3, 4]
。而在案例2中,您直接修改引用。在案例1中做同样的事情就像是:
[array1].each do |arr|
arr.each_index do |i|
arr[i]+=3
end
end
=> [[3,4]]
答案 2 :(得分:0)
.each
只是依次调用该块的每个元素(在本例中为[array1]
)。传递参数只是将其赋值给参数。您的示例可以简化为以下内容:
# CASE 1:
array1 = [0, 1]
arr = array1
arr = [3, 4]
array1
=> [0, 1]
# CASE 2:
array1 = [0, 1]
arr = array1
arr.delete_if { |ele| ele == 0 }
array1
=> [1]