According to the "well ground rubyist" in the example c "contains" or "points at" an anonymous class. Am I right, that C is not an anonymous class? That's really a little bit confusing.
>> c = Class.new
=> #<Class:0x0000000006c4bd40>
>> o1 = c.new
=> #<#<Class:0x0000000006c4bd40>:0x0000000006b81ec8>
>> o1.class
=> #<Class:0x0000000006c4bd40>
>>
>> C = Class.new
=> C
>> o2 = C.new
=> #<C:0x0000000006494480>
>> o2.class
=> C
CodePudding user response:
Class.new
creates a new anonymous (unnamed) classc = Class.new
creates a new anonymous class and assigns it to the local variablec
C = Class.new
creates a new anonymous class and assigns it to the constantC
Although both assignments look almost identical, there's a subtle but important difference: assigning an anonymous class to a constant sets the name
of that class to the name of the constant:
c = Class.new
c.name #=> nil
C = Class.new
C.name #=> "C"
This is also mentioned in the docs for Class.new
:
You can give a class a name by assigning the class object to a constant.
At this point, the class is no longer anonymous. It now has a name and we can refer to it using that name in the form of the constant C
.
CodePudding user response:
A class stored as a constant has a global scope, unless you take measures to prevent that. In that sense it is "named" everywhere. A variable is confined to a much narrower scope if it's not a global. So "anonymous" in this case implies "anonymous in the global namespace". c
is while C
isn't.
CodePudding user response:
The concept of an "anonymous" or "named" class doesn't really make sense in Ruby. A class is just an object like any other object. We don't have "anonymous" or "named" integers or strings either.
This is different from programming languages like Java with a nominative type system, where a type having or not having a name makes a big difference.
This is really important to understand: a class is just an object that happens to be an instance of the Class
class. Nothing special.
What classes do have, is a method named Module#name
, but again, there is nothing special about that method. You can add a #name
method to your own classes as well.
The only thing that is special is that when a class (actually a module) is assigned the first time to a constant, the path to that constant becomes the return value of Module#name
:
a = Class.new
a.name #=> nil
b = a
b.name #=> nil
module A; module B; module C; end end end
A::B::C::D = b
a.name #=> 'A::B::C::D'
A::B::C::D = nil
A::B::C.send(:remove_const, :D)
A::B::C = nil
A::B.send(:remove_const, :C)
A::B = nil
A.send(:remove_const, :B)
A = nil
Object.send(:remove_const, :A)
a.name #=> 'A::B::C::D'
So, as you can see, the distinction between "anonymous" and "named" is practically non-existent, and even if you could construct a meaningful definition, then the distinction is still irrelevant.