2

メタクラスと Ruby のオブジェクト モデルにおけるメタクラスの位置付けに関するこの投稿には、クラス階層図があります。その中で、Class:Class(Classの singleton クラス) はそれ自体のインスタンスですが、 のインスタンスであるべきだと思いますClass。別の言い方をすれば、class_singletonclass次のようなオブジェクトがあるとします。

class_singletonclass = Class.singleton_class
# => #<Class:Class>

内部クラスのポインターはどこをklass指していますか? のクラスメソッド(シングルトンメソッド)を定義したとすると、 の場合、はどこをklass指しているのか?ClassClass

Classすでにクラスメソッドが定義されていることに気付きました。Classこれは特別なことであり、MRI には独自の C 実装があるため、クラス メソッドを追加すると適切なメタクラスが作成されると思います。この仮定は間違っていますか?

class.cMRIで次のことがわかりました。

/*!
 * A utility function that wraps class_alloc.
 *
 * allocates a class and initializes safely.
 * \param super     a class from which the new class derives.
 * \return          a class object.
 * \pre  \a super must be a class.
 * \post the metaclass of the new class is Class.
 */
VALUE
rb_class_boot(VALUE super)
{
    VALUE klass = class_alloc(T_CLASS, rb_cClass);

    RCLASS_SET_SUPER(klass, super);
    RCLASS_M_TBL(klass) = st_init_numtable();

    OBJ_INFECT(klass, super);
    return (VALUE)klass;
}

この行は、のメタクラスが実際にある\post the metaclass of the new class is Class.ことを示唆しており、これはすべてのメタクラスに当てはまります。ClassClass

4

1 に答える 1

1

inheritance上記のリンク先の投稿の拡張機能を Ruby 2.0 に適合させました。

継承.c

#include "ruby.h"

VALUE real_super(VALUE self)
{
  return RCLASS_SUPER(RBASIC(self)->klass);
}

VALUE real_klass(VALUE self)
{
  return RBASIC(self)->klass;
}

void Init_inheritance()
{
  rb_define_method(rb_cClass,"real_super",real_super,0);
  rb_define_method(rb_cClass,"real_klass",real_klass,0);
}

test.rb

require_relative 'inheritance'

puts "Object real class: #{Object.real_klass}"
puts "Object real superclass: #{Object.real_super}"

puts "Class real class: #{Class.real_klass}"
puts "Class real superclass: #{Class.real_super}"

puts "Class metaclass real class: #{Class.singleton_class.real_klass}"
puts "Class metaclass real superclass: #{Class.singleton_class.real_super}"

puts "Object metaclass real class: #{Object.singleton_class.real_klass}"
puts "Object metaclass real superclass: #{Object.singleton_class.real_super}"

puts "An object singleton class real class: #{Object.new.singleton_class.real_klass}"
puts "An object singleton class real superclass: #{Object.new.singleton_class.real_super}"

出力は次のとおりです。

Object real class: #<Class:Object>
Object real superclass: #<Class:BasicObject>
Class real class: #<Class:Class>
Class real superclass: #<Class:Module>
Class metaclass real class: #<Class:#<Class:Class>>
Class metaclass real superclass: #<Class:#<Class:Module>>
Object metaclass real class: #<Class:#<Class:Object>>
Object metaclass real superclass: #<Class:#<Class:BasicObject>>
An object singleton class real class: #<Class:Object>
An object singleton class real superclass: #<Class:BasicObject>

そのため、メタクラスの場合、klassはメタクラス自体を指します (図のその部分は正しいですが、 と のいくつかの不一致を指しています)。

于 2013-09-13T09:24:48.983 に答える