Why is an object different from iterating inside and out?

I assigned the class to constant Foo and reassigned Foo to something else:

 class Foo; end Foo = nil 

In the main environment, Foo refers to a newly assigned object:

 p Foo # => nil 

But, in some iteration (I'm not sure which one), Foo refers to the previous object:

 ObjectSpace.each_object(Class).select{|c| c.name == "Foo"} .each{|c| pc, c.instance_of?(Class)} # => Foo true 

Why is this?

+4
source share
3 answers

Assigning nil constant Foo does not affect the created class. It still exists, although you can no longer reference it with Foo (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 name , creating a class with

 class Foo; end Foo.name # => "Foo" 

assigns it to constant Foo , like:

 Foo = Class.new Foo.name # => "Foo" 

It also sets its name , but that does not make it a class. You can also 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" 

After installation, it does not change:

 Baz = foo foo.name # => "Bar" 
+4
source

The class you created exists and is accessible from the main ObjectSpace until it collects garbage.

The constant name Foo is just a reference to the class object. Its internal name remains "Foo", even if available through other variable or constant names.

Try this to demonstrate that even β€œrenamed” a class name is still β€œFoo”:

 class Foo; end a = Foo Foo = nil puts a.name # prints Foo 
+2
source

Foo tied to nil , both inside and outside the block. What makes you think that this is not so? You don't even reference Foo inside the block.

+1
source

Source: https://habr.com/ru/post/1480513/


All Articles