The Class/Object Paradox confusion
You can see the problem in this diagram:
(source: phrogz.net)
All object instances inherit from Object
. All classes are objects, and Class
is a class, therefore Class
is an object. However, object instances inherit from their class, and Object
is an instance of the Class
class, therefore Object
itself gets methods from Class
.
As you can see in the diagram, however, there isn't a circular lookup loop, because there are two different inheritance 'parts' to every class: the instance methods and the 'class' methods. In the end, the lookup path is sane.
N.B.: This diagram reflects Ruby 1.8, and thus does not include the core BasicObject
class introduced in Ruby 1.9.
Ruby metaclass confusion
how do this work
Easy: it doesn't. Not in Ruby, anyway.
Just like in most other languages, there are some core entities that are simply assumed to exist. They fall from the sky, materialize out of thin air, magically appear.
In Ruby, some of those magic things are:
Object
doesn't have a superclass, but you cannot define a class with no superclass, the implicit direct superclass is alwaysObject
. [Note: there may be implementation-defined superclasses ofObject
, but eventually, there will be one which doesn't have a superclass.]Object
is an instance ofClass
, which is a subclass ofObject
(which means that indirectlyObject
is an instance ofObject
itself)Class
is a subclass ofModule
, which is an instance ofClass
Class
is an instance ofClass
None of these things can be explained in Ruby.
BasicObject
, Object
, Module
and Class
all need to spring into existence at the same time because they have circular dependencies.
Just because this relationship cannot be expressed in Ruby code, doesn't mean the Ruby Language Specification can't say it has to be so. It's up to the implementor to figure out a way to do this. After all, the Ruby implementation has a level of access to the objects that you as a programmer don't have.
For example, the Ruby implementation could first create BasicObject
, setting both its superclass
pointer and its class
pointer to null
.
Then, it creates Object
, setting its superclass
pointer to BasicObject
and its class
pointer to null
.
Next, it creates Module
, setting its superclass
pointer to Object
and its class
pointer to null
.
Lastly, it creates Class
, setting its superclass
pointer to Module
and its class
pointer to null
.
Now, we can overwrite BasicObject
's, Object
's, Module
's, and Class
's class
pointer to point to Class
, and we're done.
This is easy to do from outside the system, it just looks weird from the inside.
Once they do exist, however, it is perfectly possible to implement most of their behavior in plain Ruby. You only need very barebones versions of those classes, thanks to Ruby's open classes, you can add any missing functionality at a later time.
In your example, the class Class
is not creating a new class named Class
, it is reopening the existing class Class
, which was given to us by the runtime environment.
So, it is perfectly possible to explain the default behavior of Class#new
in plain Ruby:
class Class
def new(*args, &block)
obj = allocate # another magic thing that cannot be explained in Ruby
obj.initialize(*args, &block)
return obj
end
end
[Note: actually, initialize
is private, so you need to use obj.send(:initialize, *args, &block)
to circumvent the access restriction.]
BTW: Class#allocate
is another one of those magic things. It allocates a new empty object in Ruby's object space, which is something that cannot be done in Ruby. So, Class#allocate
is something that has to be provided by the runtime system as well.
How the BasicObject, Object, and Kernel interact each other?
You are confusing two meanings of "is": "instance of" and "subclass of".
1) Regarding subclass relation:
Class
is a subclass ofModule
.Module
is a subclass ofObject
.Object
is a subclass ofBasicObject
.
And due to transitivity, Class
is a subclass of Object
and of BasicObject
, and Module
is a subclass of BasicObject
. But there is no circularity here. For example, BasicObject
is not a subclass of Class
, Module
, or Object
.
2) Regarding instantiation relation:
Class
is an instance ofClass
(as well as (kind) ofModule
,Object
,BasicObject
).Module
is an instance ofClass
(as well as (kind) ofModule
,Object
,BasicObject
).Object
is an instance ofClass
(as well as (kind) ofModule
,Object
,BasicObject
).BasicObject
is an instance ofClass
(as well as (kind) ofModule
,Object
,BasicObject
).
But there is no circularity in instantiation relation. Circularity is a notion defined on transitive relations. For example, If A → B
and B → C
, then it follows that A → C
due to transitivity, and if it is C → A
as well, then there is circularity. But instantiation relation is not transitive. "A is an instance of B" and "B is an instance of C" does not mean that "A is an instance of C". So circularity cannot be defined on instantiation relation in a non-trivial way.
Can someone explain the Class.superclass.class.superclass paradox?
TL;DR: Module is the superclass of Class. Module is an instance of Class.
Let me try to explain it more clearly. Please forgive my handwritten drawings - I don't have any fancy drawing software.
Every class in Ruby has 1 superclass*.
*Except for BasicObject, which doesn't have a superclass.
Read the above graphic like this: The superclass of Float is Numeric. The superclass of Numeric is Object, etc...
When you instantiate an object, the object will be an instance of some class. For example, "Nathan" is an instance of the String class. So is "Joe" or "John". 1 is an instance of the Fixnum class, as are 2, 3, 4, etc...
Read the above graphic like this: "Joe" is an instance of String. 1 is an instance of Fixnum, etc...
Well, in Ruby, unlike in most other languages, Class is a just another class, and it can be instantiated, too, just like Fixnum or String.
Read the above graphic like this: 0.01 is an instance of Float. String is an instance of Class, etc...
Realize that Fixnum is an instance of Class, just like "Nathan" is an instance of String. Just like "John" is an instance of String, Float is just an instance of Class. Every class is just an an instance of Class, even Class itself!
Whenever you write a new class in your app, you are just instantiating a new object whose class is Class, just like Hash.new instantiates a new Hash, or "Nathan" instantiates a new String.
# By running this, you will be instantiating a new Class, and
# it will be named Post
class Post < ActiveRecord::Base
end
# Here is another perfectly valid way to write the above code:
Post = Class.new(ActiveRecord::Base)
# you can even instantiate a Class without giving it an explicit name:
x = Class.new(ActiveRecord::Base)
# and since your new things are classes, they can be instantiated
obj1 = Post.new
obj2 = x.new
Furthermore, Module is just another instance of Class. Whenever you write a new module in your app, you are just instantiating a new Module.
# this will instantiate a new Module, and assign it to Foo
module Foo
end
# Here is another perfectly valid way to write the above code:
Foo = Module.new
# you can even instantiate a Module without giving it an explicit name.
m = Module.new
An aside: A Module is just a collection of methods and constants. Classes are also a collection of methods and constants, but with the added functionality of being able to be instantiated. A module cannot be instantiated. That is, m.new
will not work.
So, referring back to the top graphic, your question can be answered directly:
So a class's parent is module, but module is a class?
You can see from the top graphic: Module is the superclass of Class.
From the bottom graphic: Module is an instance of Class.
Understanding class and object in scala
I'll try to explain what a Scala object
is from the perspective of someone who knows Java.
In Java, you can define "normal" class members and static
class members. When something (for example a member variable) is static
in Java, then there's only one instance of that member variable, which is shared by all instances of the class.
In Scala, there is no static
. Compared to Java: whatever you would make static
in Java, you would put in an object
in Scala.
A Scala object
is a singleton - there's only a single instance of it, just like static
members in Java of which there's only a single instance.
I hope that makes it a little bit more clear what a Scala object
is exactly.
A Scala object
can extend classes or traits just like any other class or trait, so that it inherits whatever was defined in the class or trait that it extends. There's really no reason why this should not be possible.
Note that if you have a class
and an object
with the same name, then those two belong together - they can see each other's private members. The object
is called the companion object of the class.
Note that this does not mean that the object
is an instance of the class. It is not - it is a separate thing that stands beside the class. Maybe your confusion about the class and object extending different traits comes from a misunderstanding about that point.
Why does python confuse my packages for modules
In Java imports are just syntactic sugar (no really). In python they are actual statements and they are resolved based on complex rules involving the sys.path variable and the current working directory. The correct way to run a python script (aka module) that resides in a package is:
$ C://path//to//python//interpreter.exe -m packagename.modulename
So in your case
$ cd "C:\Users\Ben\VsCode\python\"
$ C://path//to//python//interpreter.exe -m classgenerator.parsing.class_dict
This way the relative imports are resolved correctly as "C:\Users\Ben\VsCode\python" is automatically added to the sys.path and python scans it a finds the package classgenerator and the subpackage parsing
Related Topics
"Gem Install Rails" Fails With Dns Error
How to Hide Password Input from Terminal in Ruby Script
Find Number of Months Between Two Dates in Ruby on Rails
Rails Object Relationships and Json Rendering
Unable to Obtain Stable Firefox Connection in 60 Seconds (127.0.0.1:7055)
Ruby Templates: How to Pass Variables into Inlined Erb
Why Isn't Current Directory on My Ruby Path
How to Check a Checkbox in Capybara
Parallel Assignment Operator in Ruby
How to Group by Count in Array Without Using Loop
Rspec: Expect VS Expect With Block - What's the Difference
Using Layouts in Haml Files Independently of Rails
Rails Engines Extending Functionality
Rails 4.0 Strong Parameters Nested Attributes With a Key That Points to a Hash