これはどのように機能しますか
簡単:そうではありません。とにかく、Rubyではありません。
他のほとんどの言語と同様に、単に存在すると想定されるコアエンティティがいくつかあります。それらは空から落ち、薄い空気から実体化し、魔法のように現れます。
Rubyでは、これらの魔法のいくつかは次のとおりです。
Object
スーパークラスはありませんが、スーパークラスのないクラスを定義することはできません。暗黙の直接スーパークラスは常にObject
です。[注:の実装定義のスーパークラスが存在する可能性がありますがObject
、最終的には、スーパークラスを持たないスーパークラスが存在することになります。]
Object
のインスタンスでありClass
、のサブクラスですObject
(つまり、間接的にそれ自体Object
のインスタンスですObject
)
Class
のサブクラスでありModule
、のインスタンスです。Class
Class
のインスタンスですClass
これらのことはどれもRubyでは説明できません。
BasicObject
、、およびすべてはObject
、循環依存関係があるため、同時に存在する必要があります。Module
Class
この関係をRubyコードで表現できないからといって、Ruby言語仕様がそうしなければならないと言えないわけではありません。これを行う方法を見つけるのは実装者次第です。結局のところ、Rubyの実装には、プログラマーとしてのあなたが持っていないオブジェクトへのアクセスのレベルがあります。
たとえば、Ruby実装は最初にを作成し、そのポインタとそのポインタBasicObject
の両方をに設定できます。superclass
class
null
次に、を作成し、ポインタをObject
に設定し、ポインタsuperclass
をに設定します。BasicObject
class
null
次に、を作成し、ポインタをModule
に設定し、ポインタsuperclass
をに設定します。Object
class
null
最後に、を作成し、ポインタをClass
に設定し、ポインタsuperclass
をに設定します。Module
class
null
BasicObject
これで、を指すように's 、Object
' s、Module
's、およびClass
'のclass
ポインタを上書きできます。これでClass
完了です。
これはシステムの外部から簡単に実行でき、内部からは奇妙に見えます。
ただし、それらが存在すると、それらの動作のほとんどをプレーンなRubyで実装することは完全に可能です。Rubyのオープンクラスのおかげで、これらのクラスの非常に必要最低限のバージョンのみが必要です。不足している機能は後で追加できます。
あなたの例では、class Class
はという名前の新しいクラスを作成していません。ランタイム環境から提供された既存のクラスClass
を再度開いています。Class
したがって、Class#new
プレーンな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
[注:実際にinitialize
はプライベートであるため、アクセス制限を回避するために使用する必要がありobj.send(:initialize, *args, &block)
ます。]
ところで:Class#allocate
それらの魔法のもう一つです。これは、Rubyのオブジェクトスペースに新しい空のオブジェクトを割り当てます。これは、Rubyでは実行できないことです。したがって、Class#allocate
ランタイムシステムによっても提供される必要があるものです。