Last active
August 29, 2015 14:21
-
-
Save JoshCheek/cf7f587258cc721755d6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'objspace' | |
class A | |
# When we include a module, it makes an invisible "included class" (T_ICLASS), | |
# and places it in the inheritance hierarchy, as the superclass. | |
# Hence A the inclusion, A no longer has a direct reference to Object, | |
# it now has a direct reference to the included class | |
ObjectSpace.reachable_objects_from(self) # => [#<InternalObject:0x007f8cd29343b8 T_CLASS>, "A", Object] | |
m = Module.new | |
include m | |
ObjectSpace.reachable_objects_from(self) # => [#<InternalObject:0x007f8cd29343b8 T_CLASS>, "A", #<InternalObject:0x007f8cd2934020 T_ICLASS>] | |
# The included class keeps a reference to the module, thus when we ask for things like .ancestors, | |
# it gives us the module instead of the included class. This is seen as an implementation detail. | |
A.ancestors # => [A, #<Module:0x007f8cd2934048>, Object, PP::ObjectMixin, Kernel, BasicObject] | |
# It must go through the included class to access Object, or the module | |
iclass = ObjectSpace.reachable_objects_from(self).last | |
iclass # => #<InternalObject:0x007f8cd2934020 T_ICLASS> | |
ObjectSpace.reachable_objects_from(iclass) # => [#<Module:0x007f8cd2934048>, "#<Module:0x007f8cd2934048>", Object] | |
# The module does not have a name until it is assigned to a constant. | |
# But even then, that name is not generated until it is asked for. | |
Object.const_set(:M, m) | |
ObjectSpace.reachable_objects_from(iclass) # => [M, "#<Module:0x007f8cd2934048>", Object] | |
m.name # => "M" | |
ObjectSpace.reachable_objects_from(iclass) # => [M, "M", Object] | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'objspace' | |
# When we define our first singleton method, that creates a new class to house the method, | |
# and places the class it at the object's class pointer. | |
# This means the object has no direct reference to its original class, it must go through the superclass. | |
# This also explains how every object can have a singleton class: they are created lazily | |
o = Object.new | |
ObjectSpace.reachable_objects_from(o) # => [Object] | |
def o.zomg; end | |
ObjectSpace.reachable_objects_from(o) # => [#<InternalObject:0x007ffb94814c90 T_CLASS>] | |
sclass = ObjectSpace.reachable_objects_from(o).first | |
ObjectSpace._id2ref(sclass.internal_object_id) # => #<Class:#<Object:0x007ffb94814f60>> | |
o.singleton_class # => #<Class:#<Object:0x007ffb94814f60>> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment