class_singleton_instance.patch

Zachary Scott, 11/19/2012 08:43 AM

Download (4.29 KB)

View differences:

NEWS
62 62
    * extended method:
63 63
      * Module#define_method accepts a UnboundMethod from a Module.
64 64

  
65
  * Class
66
    * added method:
67
      * added Class#singleton_instance returning the attached instance from a
68
        singleton Class. This is the reversed version of the
69
        Kernel#singleton_class getter method.
70

  
65 71
  * NilClass
66 72
    * added method:
67 73
      * added nil.to_h which returns {}
class.c
1294 1294
    return Qnil;
1295 1295
}
1296 1296

  
1297
static inline VALUE
1298
special_singleton_instance_of(VALUE obj)
1299
{
1300
    SPECIAL_SINGLETON(rb_cNilClass, Qnil);
1301
    SPECIAL_SINGLETON(rb_cFalseClass, Qfalse);
1302
    SPECIAL_SINGLETON(rb_cTrueClass, Qtrue);
1303
    rb_raise(rb_eTypeError, "not singleton class");
1304
}
1305

  
1297 1306
VALUE
1298 1307
rb_special_singleton_class(VALUE obj)
1299 1308
{
1300 1309
    return special_singleton_class_of(obj);
1301 1310
}
1302 1311

  
1312
VALUE
1313
rb_special_singleton_instance(VALUE obj)
1314
{
1315
    return special_singleton_instance_of(obj);
1316
}
1317

  
1303 1318
/*!
1304 1319
 * \internal
1305 1320
 * Returns the singleton class of \a obj. Creates it if necessary.
internal.h
62 62
VALUE rb_obj_public_methods(int argc, VALUE *argv, VALUE obj);
63 63
int rb_obj_basic_to_s_p(VALUE);
64 64
VALUE rb_special_singleton_class(VALUE);
65
VALUE rb_special_singleton_instance(VALUE);
65 66
void Init_class_hierarchy(void);
66 67

  
67 68
/* compile.c */
object.c
1744 1744
    return super;
1745 1745
}
1746 1746

  
1747
/*
1748
 *  call-seq:
1749
 *     class.singleton_instance -> an_object
1750
 *
1751
 *  Returns the attached singleton instance of <i>class</i>.
1752
 *
1753
 *     klass = "Hello".singleton_class
1754
 *     klass.singleton_instance => "Hello"
1755
 *
1756
 *  If the given class isn't a singleton class, it raises a TypeError.
1757
 *
1758
 */
1759

  
1760
VALUE
1761
rb_class_singleton_instance(VALUE klass)
1762
{
1763
    if(FL_TEST(klass, FL_SINGLETON)) {
1764
	return rb_iv_get(klass, "__attached__");
1765
    } else {
1766
	return rb_special_singleton_instance(klass);
1767
    }
1768
}
1769

  
1747 1770
VALUE
1748 1771
rb_class_get_superclass(VALUE klass)
1749 1772
{
......
2989 3012
    rb_define_method(rb_cClass, "initialize", rb_class_initialize, -1);
2990 3013
    rb_define_method(rb_cClass, "initialize_copy", rb_class_init_copy, 1); /* in class.c */
2991 3014
    rb_define_method(rb_cClass, "superclass", rb_class_superclass, 0);
3015
    rb_define_method(rb_cClass, "singleton_instance", rb_class_singleton_instance, 0);
2992 3016
    rb_define_alloc_func(rb_cClass, rb_class_s_alloc);
2993 3017
    rb_undef_method(rb_cClass, "extend_object");
2994 3018
    rb_undef_method(rb_cClass, "append_features");
test/ruby/test_class.rb
206 206
    INPUT
207 207
  end
208 208

  
209
  def test_singleton_instance
210
    o = Object.new
211
    c = o.singleton_class
212
    assert_equal(o, c.singleton_instance)
213
  end
214

  
215
  def test_no_singleton_instance
216
    assert_raise(TypeError) { String.singleton_instance }
217
  end
218

  
219
  def test_class_singleton_instance
220
    c = Object.singleton_class
221
    assert_equal(Object, c.singleton_instance)
222
  end
223

  
224
  def test_immediate_singleton_instance
225
    assert_equal(true, TrueClass.singleton_instance)
226
    assert_equal(false, FalseClass.singleton_instance)
227
    assert_equal(nil, NilClass.singleton_instance)
228
  end
229

  
209 230
  def test_uninitialized
210 231
    assert_raise(TypeError) { Class.allocate.new }
211 232
    assert_raise(TypeError) { Class.allocate.superclass }
212
-