I have a class, which de-constructs incoming string into a nested array cascade.
For example for an input abcde it will produce a [[[[a,b],c],d],e] array.
Just now, if I access to set any top level value of cascade, the []=(index, value) method of my class will be invoked. But I also need to catch the access to the nested array within cascade of arbitrary level.
See example below, where accessing x[0][0] obviously doesn’t invoke a class method []=. So, is it possible to catch that access within a class method (or at least in a different way)?
class MyClass
attr_accessor :cascade
def initialize string
build_cascade string.split(//)
end
def build_cascade array
if array.length > 2
array[0] = array[0..1]
array.delete_at(1)
build_cascade array
else
@cascade = array
end
end
def []=(index, value)
puts 'You\'ve just tried to set \''+value.to_s+'\' for \''+index.to_s+'\' of @cascade!'
end
def [](index)
@cascade[index]
end
end
x = MyClass.new('abcdefghigk')
puts x.inspect
x[0] = 5 # => You've just tried to set '5' for '0' of @cascade!
x[0][0] = 10 #= > ~ no output ~
The problem is that you are calling []= on the sub-array contained within your main array.
in other words, you are calling [] on your class, which you implement to return that array element, and then []= on a generic Array, which you have not blocked write access to.
you could implement the structure to have your class create its subarrays by using other instances of MyClass, or you could overwrite the []= method of Array to restrict access.
Its also worth noting that depending on how this would be used, overwriting methods on a class like Array is not usually a great idea so you might want go for something like my first suggestion.