Reputation: 3494
How does one alter self
in an Array
to be a totally new array? How do I fill in the commented portion below?
class Array
def change_self
#make this array be `[5,5,5]`
end
end
I understand this: Why can't I change the value of self? and know I can't just assign self
to a new object. When I do:
arr = [1,2,3,4,5]
arr
contains a reference to an Array
object. I can add a method to Array
class that alters an array, something like:
self[0] = 100
but is it possible to change the length of the array referenced by arr
?
How are these values stored in the Array
object?
Upvotes: 0
Views: 163
Reputation: 369458
You are asking three very different questions in your title and in your text:
Is it possible to alter an
Array
object's length using anArray
method?
Yes, there are 20 methods which can (potentially) change the length of an Array
:
<<
increases the length by 1[]=
can alter the length arbitrarily, depending on argumentsclear
sets the length to 0compact!
can decrease the length, depending on contentsconcat
can increase the length, depending on argumentsdelete
can decrease the length, depending on arguments and contentsdelete_at
can decrease the length, depending on argumentsdelete_if
/ reject!
can decrease the length, depending on arguments and contentsfill
can increase the length, depending on argumentsinsert
increases the lengthkeep_if
/ select!
can decrease the length, depending on arguments and contentspop
decreases the lengthpush
increases the lengthreplace
can alter the length arbitrarily, depending on arguments and contents (it simply replaces the Array
completely with a different Array
)shift
decreases the lengthslice!
decreases the lengthuniq!
can decrease the length, depending on contentsunshift
increases the lengthWhen monkey patching the Array class, how does one alter "self" to be a totally new array? How do I fill in the commented portion below?
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
How are these values actually stored in the
Array
object?
We don't know. The Ruby Language Specification does not prescribe any particular storage mechanism or implementation strategy. Implementors are free to implement Array
s any way they like, as long as they obey the contracts of the Array
methods.
As an example, here's the Array
implementation in Rubinius, which I find fairly readable (at least more so than YARV):
vm/builtin/array.cpp
: certain core methods and data structureskernel/bootstrap/array.rb
: a minimal implementation for bootstrapping the Rubinius kernelkernel/common/array.rb
: the bulk of the implementationFor comparison, here is Topaz's implementation:
And JRuby:
Upvotes: 6
Reputation: 23317
arr = [1,2,3,4,5]
arr.replace([5,5,5])
I wouldn't monkey-patch a new method into Array; especially since it already exists. Array#replace
Upvotes: 4
Reputation: 15560
As Array
are mutables, you can alter it's contents:
class Array
def change_self
self.clear
self.concat [5, 5, 5]
end
end
You modify the array so it becomes empty, and then add all the elements from the target array. They still are two different objects (ie, myAry.object_id
would differ from [5, 5, 5].object_id
), but now they are equivalent arrays.
Moreover, the array still is the same that before - just it's content changed:
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}"
Anyway, I really don't know why one would want to do this - are you solving the right problem, or just kidding with the language?
Upvotes: 2