类 Class
扩展任何 Class
以包含 json_creatable? 方法。
Ruby 中的类是一等对象——每个类都是 Class
类的实例。
通常,您可以使用以下方式创建一个新类
class Name # some code describing the class behavior end
创建新类时,会初始化一个 Class
类型的对象,并将其分配给一个全局常量(在本例中为 Name)。
当调用 Name.new
来创建一个新对象时,默认情况下会运行 Class
中的 new
方法。这可以通过覆盖 Class 中的 new
来演示。
class Class alias old_new new def new(*args) print "Creating a new ", self.name, "\n" old_new(*args) end end class Name end n = Name.new
产生
Creating a new Name
类、模块和对象是相互关联的。在下面的图中,垂直箭头表示继承,括号表示元类。所有元类都是类 ‘Class’ 的实例。
+---------+ +-... | | | BasicObject-----|-->(BasicObject)-------|-... ^ | ^ | | | | | Object---------|----->(Object)---------|-... ^ | ^ | | | | | +-------+ | +--------+ | | | | | | | | Module-|---------|--->(Module)-|-... | ^ | | ^ | | | | | | | | Class-|---------|---->(Class)-|-... | ^ | | ^ | | +---+ | +----+ | | obj--->OtherClass---------->(OtherClass)-----------...
公共类方法
源代码
static VALUE rb_class_initialize(int argc, VALUE *argv, VALUE klass) { VALUE super; if (RCLASS_SUPER(klass) != 0 || klass == rb_cBasicObject) { rb_raise(rb_eTypeError, "already initialized class"); } if (rb_check_arity(argc, 0, 1) == 0) { super = rb_cObject; } else { super = argv[0]; rb_check_inheritable(super); if (super != rb_cBasicObject && !RCLASS_SUPER(super)) { rb_raise(rb_eTypeError, "can't inherit uninitialized class"); } } RCLASS_SET_SUPER(klass, super); rb_make_metaclass(klass, RBASIC(super)->klass); rb_class_inherited(super, klass); rb_mod_initialize_exec(klass); return klass; }
使用给定的超类(如果没有给出参数,则为 Object
)创建一个新的匿名(未命名)类。您可以通过将类对象分配给常量来给类命名。
如果给出了一个块,它将传递给类对象,并且该块将像 class_eval
一样在该类的上下文中进行评估。
fred = Class.new do def meth1 "hello" end def meth2 "bye" end end a = fred.new #=> #<#<Class:0x100381890>:0x100376b98> a.meth1 #=> "hello" a.meth2 #=> "bye"
如果您想像对待常规类一样对待它,请将该类分配给一个常量(名称以大写字母开头)。
公共实例方法
源代码
static VALUE rb_class_alloc_m(VALUE klass) { rb_alloc_func_t allocator = class_get_alloc_func(klass); if (!rb_obj_respond_to(klass, rb_intern("allocate"), 1)) { rb_raise(rb_eTypeError, "calling %"PRIsVALUE".allocate is prohibited", klass); } return class_call_alloc_func(allocator, klass); }
为 class 类的对象分配空间,并且不在新实例上调用 initialize。返回的对象必须是 class 的实例。
klass = Class.new do def initialize(*args) @initialized = true end def initialized? @initialized || false end end klass.allocate.initialized? #=> false
源代码
VALUE rb_class_attached_object(VALUE klass) { if (!RCLASS_SINGLETON_P(klass)) { rb_raise(rb_eTypeError, "'%"PRIsVALUE"' is not a singleton class", klass); } return RCLASS_ATTACHED_OBJECT(klass); }
返回接收器是单例类的对象。
如果该类不是单例类,则引发 TypeError
。
class Foo; end Foo.singleton_class.attached_object #=> Foo Foo.attached_object #=> TypeError: `Foo' is not a singleton class Foo.new.singleton_class.attached_object #=> #<Foo:0x000000010491a370> TrueClass.attached_object #=> TypeError: `TrueClass' is not a singleton class NilClass.attached_object #=> TypeError: `NilClass' is not a singleton class
源代码
# File ext/json/lib/json/common.rb, line 893 def json_creatable? respond_to?(:json_create) end
如果可以使用此类从序列化的 JSON
字符串创建实例,则返回 true。该类必须实现一个期望哈希作为第一个参数的类方法 json_create。哈希应包含所需的数据。
源代码
VALUE rb_class_new_instance_pass_kw(int argc, const VALUE *argv, VALUE klass) { VALUE obj; obj = rb_class_alloc(klass); rb_obj_call_init_kw(obj, argc, argv, RB_PASS_CALLED_KEYWORDS); return obj; }
调用 allocate
来创建一个 class 类的新对象,然后调用该对象的 initialize 方法,并将 args 传递给它。这就是最终在使用 .new
构造对象时调用的方法。
源代码
VALUE rb_class_subclasses(VALUE klass) { return class_descendants(klass, true); }
返回一个类数组,其中接收器是该类的直接超类,不包括单例类。返回数组的顺序未定义。
class A; end class B < A; end class C < B; end class D < A; end A.subclasses #=> [D, B] B.subclasses #=> [C] C.subclasses #=> []
也会返回匿名的子类(未与常量关联)。
c = Class.new(A) A.subclasses # => [#<Class:0x00007f003c77bd78>, D, B]
请注意,父类不保存对子类的引用,也不阻止它们被垃圾回收。这意味着当对它的所有引用都被删除时,子类可能会消失。
# drop the reference to subclass, it can be garbage-collected now c = nil A.subclasses # It can be # => [#<Class:0x00007f003c77bd78>, D, B] # ...or just # => [D, B] # ...depending on whether garbage collector was run
源代码
VALUE rb_class_superclass(VALUE klass) { RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS)); VALUE super = RCLASS_SUPER(klass); if (!super) { if (klass == rb_cBasicObject) return Qnil; rb_raise(rb_eTypeError, "uninitialized class"); } if (!RCLASS_SUPERCLASS_DEPTH(klass)) { return Qnil; } else { super = RCLASS_SUPERCLASSES(klass)[RCLASS_SUPERCLASS_DEPTH(klass) - 1]; RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS)); return super; } }
返回 class 的超类,或 nil
。
File.superclass #=> IO IO.superclass #=> Object Object.superclass #=> BasicObject class Foo; end class Bar < Foo; end Bar.superclass #=> Foo
当给定类没有父类时,返回 nil。
BasicObject.superclass #=> nil
私有实例方法
源代码
#define rb_obj_class_inherited rb_obj_dummy1
每当创建当前类的子类时都会调用的回调。
示例
class Foo def self.inherited(subclass) puts "New subclass: #{subclass}" end end class Bar < Foo end class Baz < Bar end
产生
New subclass: Bar New subclass: Baz