これはどのように機能しますか
簡単:そうではありません。とにかく、Rubyではありません。
他のほとんどの言語と同様に、単に存在すると想定されるコアエンティティがいくつかあります。それらは空から落ち、薄い空気から実体化し、魔法のように現れます。
Rubyでは、これらの魔法のいくつかは次のとおりです。
Objectスーパークラスはありませんが、スーパークラスのないクラスを定義することはできません。暗黙の直接スーパークラスは常にObjectです。[注:の実装定義のスーパークラスが存在する可能性がありますがObject、最終的には、スーパークラスを持たないスーパークラスが存在することになります。]
ObjectのインスタンスでありClass、のサブクラスですObject(つまり、間接的にそれ自体ObjectのインスタンスですObject)
ClassのサブクラスでありModule、のインスタンスです。Class
ClassのインスタンスですClass
これらのことはどれもRubyでは説明できません。
BasicObject、、およびすべてはObject、循環依存関係があるため、同時に存在する必要があります。ModuleClass
この関係をRubyコードで表現できないからといって、Ruby言語仕様がそうしなければならないと言えないわけではありません。これを行う方法を見つけるのは実装者次第です。結局のところ、Rubyの実装には、プログラマーとしてのあなたが持っていないオブジェクトへのアクセスのレベルがあります。
たとえば、Ruby実装は最初にを作成し、そのポインタとそのポインタBasicObjectの両方をに設定できます。superclassclassnull
次に、を作成し、ポインタをObjectに設定し、ポインタsuperclassをに設定します。BasicObjectclassnull
次に、を作成し、ポインタをModuleに設定し、ポインタsuperclassをに設定します。Objectclassnull
最後に、を作成し、ポインタをClassに設定し、ポインタsuperclassをに設定します。Moduleclassnull
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ランタイムシステムによっても提供される必要があるものです。