I assigned a class to a constant Foo
, and reassigned Foo
to something else:
class Foo; end
Foo = nil
In the main
environment, Foo
refers to the newly assigned object:
p Foo # => nil
But, within an iteration of some kind, (I am not sure which), Foo
refers to the previous object:
ObjectSpace.each_object(Class).select{|c| c.name == "Foo"}
.each{|c| p c, c.instance_of?(Class)}
# => Foo
true
Why is this?
Assigning nil
to the constant Foo
doesn't affect the created class. It still exists, although you cannot refer to it with Foo
anymore (unless you reassign the class object to Foo
again).
class Foo; end
Foo.object_id
# => 70210590718440
Foo = nil
Foo.object_id
# => 4
Foo = ObjectSpace._id2ref(70210590718440)
Foo.object_id
# => 70210590718440
Regarding the name
, creating a class with:
class Foo; end
Foo.name
# => "Foo"
assigns it to the contant Foo
, just like:
Foo = Class.new
Foo.name
# => "Foo"
It also sets its name
, but this doesn't make it a class. You can as well create classes without a name:
foo = Class.new
foo.name
# => nil
Assigning an unnamed class to a constant sets its name:
Bar = foo
foo.name
# => "Bar"
Once set, it doesn't change:
Baz = foo
foo.name
# => "Bar"
The class you created exists and is reachable from the main ObjectSpace as long as it is not garbage collected.
The constant name Foo
is merely a reference to the class object. Its internal name remains "Foo", even if accessed via other variable or constant names.
Try this, to demonstrate that even 'renamed' a
, the name of the class is still "Foo":
class Foo; end
a = Foo
Foo = nil
puts a.name # prints Foo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With