如何将self
中的Array
改为全新数组?我如何填写下面的注释部分?
class Array
def change_self
#make this array be `[5,5,5]`
end
end
我理解这一点:Why can't I change the value of self?并知道我无法将self
分配给新对象。当我这样做时:
arr = [1,2,3,4,5]
arr
包含对Array
对象的引用。我可以向Array
类添加一个改变数组的方法,例如:
self[0] = 100
但是可以更改arr
引用的数组的长度吗?
这些值如何存储在Array
对象中?
答案 0 :(得分:5)
您在标题和文字中提出了三个截然不同的问题:
是否可以使用
Array
方法更改Array
对象的长度?
是的,有20种方法可以(可能)改变Array
的长度:
<<
将长度增加1 []=
可以任意改变长度,具体取决于参数clear
将长度设置为0 compact!
可以减少长度,具体取决于内容concat
可以增加长度,具体取决于参数delete
可以减少长度,具体取决于参数和内容delete_at
可以减少长度,具体取决于参数delete_if
/ reject!
可以减少长度,具体取决于参数和内容fill
可以增加长度,具体取决于参数insert
增加了篇幅keep_if
/ select!
可以减少长度,具体取决于参数和内容pop
缩短了篇幅push
增加了篇幅replace
可以根据参数和内容任意改变长度(它只是将Array
完全替换为不同的Array
)shift
缩短了篇幅slice!
缩短了篇幅uniq!
可以减少长度,具体取决于内容unshift
增加了篇幅当猴子修补Array类时,如何将“self”改为一个全新的数组?我如何填写下面的注释部分?
class Array def change_self #make this array be [5,5,5] no matter what end end
class Array
def change_self
replace([5, 5, 5])
end
end
这些值如何实际存储在
Array
对象中?
我们不知道。 Ruby语言规范没有规定任何特定的存储机制或实现策略。只要他们遵守Array
方法的约定,实现者就可以自由地实现Array
。
作为示例,这里是Rubinius中的Array
实现,我发现它相当可读(至少比YARV更多):
vm/builtin/array.cpp
:某些核心方法和数据结构kernel/bootstrap/array.rb
:引导Rubinius内核的最小实现kernel/common/array.rb
:实施的大部分内容为了进行比较,这里是Topaz的实现:
答案 1 :(得分:4)
arr = [1,2,3,4,5]
arr.replace([5,5,5])
我不会将新方法修补到Array中;特别是因为它已经存在。 Array#replace
答案 2 :(得分:2)
由于Array
是可变的,你可以改变它的内容:
class Array
def change_self
self.clear
self.concat [5, 5, 5]
end
end
修改数组使其变为空,然后添加目标数组中的所有元素。它们仍然是两个不同的对象(即,myAry.object_id
与[5, 5, 5].object_id
不同),但现在它们是等效的数组。
此外,数组仍然是以前的 - 只是它的内容发生了变化:
myAry = [1, 2, 3]
otherRef = myAry
previousId = myAry.object_id
previousHash = myAry.hash
myAry.change_self
puts "myAry is now #{myAry}"
puts "Hash changed from #{previousHash} to #{myAry.hash}"
puts "ID #{previousId} remained as #{myAry.object_id}, as it's still the same instance"
puts "otherRef points to the same instance - it shows the changes, too: #{otherRef}"
无论如何,我真的不知道为什么要这样做 - 你是在解决正确的问题,还是只是开玩笑的语言?