Module: Mass

Extended by:
Mass
Included in:
Mass
Defined in:
lib/mass.rb

Overview

Mass

This module offers the following either within the whole Ruby Heap or narrowed by namespace:

  • indexing objects grouped by class

  • counting objects grouped by class

  • printing objects grouped by class

  • locating references to a specified object

  • detaching references to a specified object (in order to be able to release the object memory using the GC)

Instance Method Summary collapse

Instance Method Details

#[](object_id) ⇒ Object

Returns the object corresponding to the passed object_id.

Example

log_line = LogLine.new
object = Mass[log_line.object_id]
log_line.object_id == object.object_id #=> true


22
23
24
# File 'lib/mass.rb', line 22

def [](object_id)
  ObjectSpace._id2ref object_id
end

#count(*mods) ⇒ Object

Returns a hash containing classes with the amount of its instances currently in the Ruby Heap. You can narrow the result by namespace.



43
44
45
46
47
48
# File 'lib/mass.rb', line 43

def count(*mods)
  index(*mods).inject({}) do |hash, (key, value)|
    hash[key] = value.size
    hash
  end
end

#detach(object, *mods, &block) ⇒ Object

Removes all references to the passed object and yielding block when given and references within entire environment removed successfully. Use at own risk.



106
107
108
# File 'lib/mass.rb', line 106

def detach(object, *mods, &block)
  _detach(object, object._reference_instances(*mods), true, &block)
end

#detach!(object, *mods, &block) ⇒ Object

Removes all references to the passed object and yielding block when given and references within passed namespaces removed successfully. Use at own risk.



112
113
114
# File 'lib/mass.rb', line 112

def detach!(object, *mods, &block)
  _detach(object, object._reference_instances(*mods), false, &block)
end

#gc!(variable = nil) ⇒ Object

A helper method after having called Mass.detach. It instructs the garbage collector to start when the optional passed variable is nil.



28
29
30
# File 'lib/mass.rb', line 28

def gc!(variable = nil)
  GC.start if variable.nil?
end

#index(*mods) ⇒ Object

Returns a hash containing classes with the object_ids of its instances currently in the Ruby Heap. You can narrow the result by namespace.



34
35
36
37
38
39
# File 'lib/mass.rb', line 34

def index(*mods)
  instances_within(*mods).inject({}) do |hash, object|
    ((hash[object.class.name] ||= []) << object.object_id).sort! if object.methods.collect(&:to_s).include?("class")
    hash
  end
end

Prints all object instances within either the whole environment or narrowed by namespace group by class.



52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/mass.rb', line 52

def print(*mods)
  stats = count(*mods)
  puts "\n"
  puts "=" * 50
  puts " Objects within #{mods ? "#{mods.collect(&:name).sort} namespace" : "environment"}"
  puts "=" * 50
  stats.keys.sort{|a, b| [stats[b], a] <=> [stats[a], b]}.each do |key|
    puts "  #{key}: #{stats[key]}"
  end
  puts " - no objects instantiated -" if stats.empty?
  puts "=" * 50
  puts "\n"
end

#references(object, *mods) ⇒ Object

Returns all references to the passed object. You can narrow the namespace of the objects referencing to the object.

Example

class A
  attr_accessor :a
end

class B
  attr_accessor :a
end

a1 = A.new
Mass.references(a1) #=> {}

a2 = A.new
a2.object_id #=> 2152675940
a2.a = a1

b = B.new
b.object_id #=> 2152681800
b.a = a1

Mass.references(a1) #=> {"A#2152675940" => ["@a"], "B#2152681800" => ["@a"]}
Mass.references(a1, A) #=> {"A#2152675940" => ["@a"]}
Mass.references(a1, B) #=> {"B#2152681800" => ["@a"]}
Mass.references(a1, Hash) #=> {}


94
95
96
97
98
99
100
101
102
# File 'lib/mass.rb', line 94

def references(object, *mods)
  return {} if object.nil?
  object._reference_instances(*mods).inject({}) do |hash, instance|
    unless (refs = extract_references(instance, object)).empty?
      hash["#{instance.class.name}##{instance.object_id}"] = refs.collect(&:to_s).sort{|a, b| a <=> b}
    end
    hash
  end
end