Reputation: 2508
I have the following Ruby code where each instance of BigClass
creates a array with instances of BigClass
(up until a maximum depth).
class BigClass
# Increase this depending on your computer performance
MAX_DEPTH = 8
def initialize(depth = 0)
@my_arr = []
5.times do |i|
unless depth > MAX_DEPTH
@my_arr << BigClass.new(depth+1)
end
end
end
end
big_class = BigClass.new
puts "Reaches here"
# This line should throw an error but instead freezes
big_class.blah
puts "Doesn't reach here"
When calling a method which doesn't exist, I expect to receive a NoMethodError
pretty much instantly, however, it seems that the larger the contents of the array in big_class
the longer it takes for the error to be produced.
Why is this?
A few options I considered:
Something I have noticed is that when it prints "Reached here" if I quit (CTRL-C) it will immediately print out the NoMethodError
. So it doesn't seem to be an issue with finding whether or not the method exists, otherwise it wouldn't know that that is the error when I quit.
Upvotes: 2
Views: 45
Reputation: 2508
I think I worked it out.
If I override the #inspect
method of BigClass
it no longer causes an issue. This makes me think that something internally is calling #inspect
when handling the error. Since the default inspect will include the instance variables, and call inspect on them as well, if there are many instance variables and they all have many instance variables, then it could take a very long time to process.
The below code shows a version which runs as I would expect:
class BigClass
# Increase this depending on your computer performance
MAX_DEPTH = 8
def initialize(depth = 0)
@my_arr = []
5.times do |i|
unless depth > MAX_DEPTH
@my_arr << BigClass.new(depth+1)
end
end
end
def inspect
"now it works"
end
end
big_class = BigClass.new
puts "Reaches here"
# Correctly raises an error now
big_class.blah_blah_blah
puts "Doesn't reach here"
Upvotes: 2