module DeepSize
class Calculator
attr_reader :size, :limited
def initialize(object, max_depth = Float::INFINITY)
@object = object
@max_depth = max_depth
@seen = {}
@size = 0
@limited = false
end
def calculate
@size = deep_size_of(@object, 0)
self
end
private
def deep_size_of(object, current_depth)
# Stop if the current depth exceeds the maximum depth
if current_depth > @max_depth
@limited = true
return 0
end
# Avoid circular references
return 0 if @seen[object.object_id]
# Mark the object as seen
@seen[object.object_id] = true
size = ObjectSpace.memsize_of(object)
# Traverse instance variables
object.instance_variables.each do |var|
size += deep_size_of(object.instance_variable_get(var), current_depth + 1)
end
# If the object is an array or a hash, traverse its elements
if object.is_a?(Array) || object.is_a?(Hash)
object.each do |*element|
size += deep_size_of(element.first, current_depth + 1)
end
end
size
end
end
end
ref