Feature #6682 ยป class_singleton_instance.patch
NEWS | ||
---|---|---|
* extended method:
|
||
* Module#define_method accepts a UnboundMethod from a Module.
|
||
* Class
|
||
* added method:
|
||
* added Class#singleton_instance returning the attached instance from a
|
||
singleton Class. This is the reversed version of the
|
||
Kernel#singleton_class getter method.
|
||
* NilClass
|
||
* added method:
|
||
* added nil.to_h which returns {}
|
class.c | ||
---|---|---|
return Qnil;
|
||
}
|
||
static inline VALUE
|
||
special_singleton_instance_of(VALUE obj)
|
||
{
|
||
SPECIAL_SINGLETON(rb_cNilClass, Qnil);
|
||
SPECIAL_SINGLETON(rb_cFalseClass, Qfalse);
|
||
SPECIAL_SINGLETON(rb_cTrueClass, Qtrue);
|
||
rb_raise(rb_eTypeError, "not singleton class");
|
||
}
|
||
VALUE
|
||
rb_special_singleton_class(VALUE obj)
|
||
{
|
||
return special_singleton_class_of(obj);
|
||
}
|
||
VALUE
|
||
rb_special_singleton_instance(VALUE obj)
|
||
{
|
||
return special_singleton_instance_of(obj);
|
||
}
|
||
/*!
|
||
* \internal
|
||
* Returns the singleton class of \a obj. Creates it if necessary.
|
internal.h | ||
---|---|---|
VALUE rb_obj_public_methods(int argc, VALUE *argv, VALUE obj);
|
||
int rb_obj_basic_to_s_p(VALUE);
|
||
VALUE rb_special_singleton_class(VALUE);
|
||
VALUE rb_special_singleton_instance(VALUE);
|
||
void Init_class_hierarchy(void);
|
||
/* compile.c */
|
object.c | ||
---|---|---|
return super;
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* class.singleton_instance -> an_object
|
||
*
|
||
* Returns the attached singleton instance of <i>class</i>.
|
||
*
|
||
* klass = "Hello".singleton_class
|
||
* klass.singleton_instance => "Hello"
|
||
*
|
||
* If the given class isn't a singleton class, it raises a TypeError.
|
||
*
|
||
*/
|
||
VALUE
|
||
rb_class_singleton_instance(VALUE klass)
|
||
{
|
||
if(FL_TEST(klass, FL_SINGLETON)) {
|
||
return rb_iv_get(klass, "__attached__");
|
||
} else {
|
||
return rb_special_singleton_instance(klass);
|
||
}
|
||
}
|
||
VALUE
|
||
rb_class_get_superclass(VALUE klass)
|
||
{
|
||
... | ... | |
rb_define_method(rb_cClass, "initialize", rb_class_initialize, -1);
|
||
rb_define_method(rb_cClass, "initialize_copy", rb_class_init_copy, 1); /* in class.c */
|
||
rb_define_method(rb_cClass, "superclass", rb_class_superclass, 0);
|
||
rb_define_method(rb_cClass, "singleton_instance", rb_class_singleton_instance, 0);
|
||
rb_define_alloc_func(rb_cClass, rb_class_s_alloc);
|
||
rb_undef_method(rb_cClass, "extend_object");
|
||
rb_undef_method(rb_cClass, "append_features");
|
test/ruby/test_class.rb | ||
---|---|---|
INPUT
|
||
end
|
||
def test_singleton_instance
|
||
o = Object.new
|
||
c = o.singleton_class
|
||
assert_equal(o, c.singleton_instance)
|
||
end
|
||
def test_no_singleton_instance
|
||
assert_raise(TypeError) { String.singleton_instance }
|
||
end
|
||
def test_class_singleton_instance
|
||
c = Object.singleton_class
|
||
assert_equal(Object, c.singleton_instance)
|
||
end
|
||
def test_immediate_singleton_instance
|
||
assert_equal(true, TrueClass.singleton_instance)
|
||
assert_equal(false, FalseClass.singleton_instance)
|
||
assert_equal(nil, NilClass.singleton_instance)
|
||
end
|
||
def test_uninitialized
|
||
assert_raise(TypeError) { Class.allocate.new }
|
||
assert_raise(TypeError) { Class.allocate.superclass }
|