Class: Object

Inherits:
BasicObject
Defined in:
(unknown)

Instance Method Summary collapse

Instance Method Details

#class=(klass) ⇒ Object

Modifies the receiver’s class to be klass. The receiver’s current class and any singleton class (and any modules that extend the object) are ignored. If the receiver is an immediate or instances of klass don’t use the same internal type as the receiver, a TypeError is raised.

Returns:



246
247
248
249
250
251
252
253
# File 'ext/evilr/evilr.c', line 246

static VALUE evilr_class_e(VALUE self, VALUE klass) {
  evilr__check_immediate(self);
  evilr__check_type(evilr__class_type(klass), self);
  evilr__check_data_type(self);

  RBASIC_SET_KLASS(self, klass);
  return self;
}

#detach_singleton_classClass

If the receiver has a singleton class, it is detached from the receiver and becomes the receiver’s class. If the receiver is an immediate, a TypeError is raised. Returns the (possibly new) class of the receiver.

Returns:



606
607
608
609
# File 'ext/evilr/evilr.c', line 606

static VALUE evilr_detach_singleton_class(VALUE self) {
  evilr__check_immediate(self);
  return evilr_detach_singleton(RBASIC_KLASS(self));
}

#dup_singleton_class(klass = Object) ⇒ Class || nil

If the receiver has a singleton class, a copy of the class is returned, and the superclass of that class is set to the given klass. Any modules that extend the object become modules included in the returned class. If the receiver does not have a singleton class, nil is returned and no changes are made. If the receiver is an immediate, a TypeError is raised.

Returns:



619
620
621
622
623
624
625
626
627
628
629
630
631
# File 'ext/evilr/evilr.c', line 619

static VALUE evilr_dup_singleton_class(int argc, VALUE *argv, VALUE self) {
  VALUE klass;
  evilr__check_immediate(self);
 
  if (!HAS_SINGLETON_CLASS(self)) {
    return Qnil;
  }
  klass = evilr__optional_class(argc, argv);
  self = rb_singleton_class_clone(self);
  evilr__reparent_class(self, klass);
  FL_UNSET(self, FL_SINGLETON);
  return self;
}

#evilr_debug_printnil

Prints to stdout the receiver and all entries in the receiver’s klass’s super chain, using the pointers of the current entry, it’s klass, iv_tbl, m_tbl, and super entry, as well as the entry’s flags. If Class or Module is given, uses their super chain, not the super chain of their klass. If the receiver is an immediate value, a TypeError is raised.

Returns:

  • (nil)


263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
# File 'ext/evilr/evilr.c', line 263

static VALUE evilr_debug_print(VALUE self) {
  if (self == NULL) {
    return Qnil;
  }
  evilr__check_immediate(self);
  switch(BUILTIN_TYPE(self)) {
    case T_CLASS:
    case T_ICLASS:
    case T_MODULE:
      printf("self %p klass %p flags 0x%lx iv_tbl %p m_tbl %p super %p\n", (void *)self, (void *)RBASIC_KLASS(self), RBASIC_FLAGS(self), (void *)RCLASS_IV_TBL(self), (void *)RCLASS_M_TBL(self), (void *)RCLASS_SUPER(self));
      self = RCLASS_SUPER(self);
      break;
    default:
      printf("self %p klass %p flags 0x%lx iv_tbl/ptr %p\n", (void *)self, (void *)RBASIC_KLASS(self), RBASIC_FLAGS(self), (void *)ROBJECT_IVPTR(self));
      self = RBASIC_KLASS(self);
      break;
  }
  return evilr_debug_print(self);
}

#extend_between(mod) {|p, c| ... } ⇒ Object

Walks the receiver’s singleton class’s super chain until it reaches the receiver’s class, yielding the previous and current entries in the super chain at every step. The first time the block returns true, mod is inserted into the super chain between the two values and the method returns immediately. Raises TypeError if mod is not a Module or if the receiver is an immediate. If the block ever returns true, the return value is mod. If the block never returns true, the return value is nil. On the first block call, the first block argument is the receiver’s singleton class, and on the last block call, the last block argument is the receiver’s class.

Yields:

  • (p, c)


556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
# File 'ext/evilr/evilr.c', line 556

static VALUE evilr_extend_between(VALUE self, VALUE mod) {
  VALUE sc, iclass, klass, prev, cur;

  evilr__check_immediates(self, mod);
  evilr__check_type(T_MODULE, mod);

  sc = rb_singleton_class(self);
  klass = rb_obj_class(self);
  rb_extend_object(self, mod);
  iclass = evilr__iclass_matching_before(sc, mod, klass);
  if (iclass == NULL) {
    rb_raise(rb_eArgError, "module already included in object's class");
  }
  evilr_unextend(self, mod);

  for (prev = sc, cur = RCLASS_SUPER(sc); prev && prev != klass; prev = cur, cur = cur ? RCLASS_SUPER(cur) : cur) {
    if (rb_yield_values(2, INCLUDE_BETWEEN_VAL(prev), INCLUDE_BETWEEN_VAL(cur)) == Qtrue) {
      RCLASS_SET_SUPER(prev, iclass);
      RCLASS_SET_SUPER(iclass, cur);
      return mod;
    }
  }
  return Qnil;
}

#flagsInteger

Returns the internal flags value of the receiver as an Integer. Raises TypeError if the receiver is an immediate.

Returns:

  • (Integer)


784
785
786
787
# File 'ext/evilr/evilr.c', line 784

static VALUE evilr_flags(VALUE self) {
  evilr__check_immediate(self);
  return UINT2NUM(RBASIC_FLAGS(self));
}

#pop_singleton_classClass || nil

Removes the closest singleton class from the receiver and returns it. If the receiver does not have a singleton class, does nothing and returns nil. Designed to be used with push_singleton_class to implement a method table stack on an object. If the receiver is an immediate, raises TypeError.

Returns:



655
656
657
658
659
660
661
662
663
664
665
666
667
# File 'ext/evilr/evilr.c', line 655

static VALUE evilr_pop_singleton_class(VALUE self) {
  VALUE klass;

  evilr__check_immediate(self);
  klass = RBASIC_KLASS(self);

  if (IS_SINGLETON_CLASS(klass)) {
    RBASIC_SET_KLASS(self, evilr__next_class(klass));  
  } else {
    klass = Qnil;
  }
  return klass;
}

#push_singleton_class(klass) ⇒ Object

Makes the given class the closest singleton class of the receiver, without changing any existing singleton class relationships. Designed to be used with pop_singleton_class to implement a method table stack on an object. If the receiver is an immediate or klass is not a class, raises TypeError.



640
641
642
643
644
645
# File 'ext/evilr/evilr.c', line 640

static VALUE evilr_push_singleton_class(VALUE self, VALUE klass) {
  evilr__check_obj_and_class(self, klass);
  evilr__reparent_class(evilr__iclass_before_next_class(klass), RBASIC_KLASS(self));
  evilr__make_singleton(self, klass);
  return klass;
}

#remove_singleton_classObject

Removes the singleton class of the receiver, detaching it from the receiver and making it a regular class. If the receiver does not currently have a singleton class, returns nil. If the receiver is an immediate, raises TypeError.



705
706
707
708
709
710
711
712
713
714
715
716
# File 'ext/evilr/evilr.c', line 705

static VALUE evilr_remove_singleton_class(VALUE self) {
  VALUE klass;
  evilr__check_immediate(self);

  if (HAS_SINGLETON_CLASS(self)) {
    klass = evilr_detach_singleton_class(self);
    RBASIC_SET_KLASS(self, evilr__next_class(klass));
  } else {
    klass = Qnil;
  }
  return klass;
}

#remove_singleton_classesnil

Removes all singleton classes from the receiver. Designed to be used with push_singleton_class and pop_singleton_class to implement a method table stack on an object, this clears the stack. If the receiver is an immediate, raises TypeError.

Returns:

  • (nil)


676
677
678
679
680
# File 'ext/evilr/evilr.c', line 676

static VALUE evilr_remove_singleton_classes(VALUE self) {
  evilr__check_immediate(self);
  RBASIC_SET_KLASS(self, rb_obj_class(self));  
  return Qnil;
}

#segfaultObject

Dereferences the NULL pointer, which should cause SIGSEGV (a segmentation fault), and the death of the process, though it could possibly be rescued.



878
879
880
881
# File 'ext/evilr/evilr.c', line 878

static VALUE evilr_segfault(VALUE self) {
  self = *(char *)NULL;
  return self;
}

#seppukuObject

Kills the current process with SIGKILL, which should terminate the process immediately without any recovery possible.



888
889
890
891
# File 'ext/evilr/evilr.c', line 888

static VALUE evilr_seppuku(VALUE self) {
  kill(getpid(), SIGKILL);
  return self;
}

#set_safe_level=(int) ⇒ Integer

Sets the $SAFE level to the given integer. If the number is greater than 4, sets it to 4. Allows lowering the $SAFE level by passing an integer lower than the current level. Returns the value passed in.

Returns:

  • (Integer)


442
443
444
445
446
447
448
449
450
451
452
453
# File 'ext/evilr/evilr.c', line 442

static VALUE evilr_set_safe_level(VALUE self, VALUE safe) {
  int s = NUM2INT(safe);
  if (s > SAFE_LEVEL_MAX) {
    s = SAFE_LEVEL_MAX;
  }
#ifdef RUBY19
  rb_set_safe_level_force(s);
#else
  ruby_safe_level = s;
#endif
  return safe;
}

#set_singleton_class(klass) ⇒ Object

Makes the given klass the singleton class of the receiver, ignoring any existing singleton class and modules extending the receiver. Modules already included in klass become modules that extend the receiver. If the receiver is an immediate or klass is not a Class, raises TypeError.



690
691
692
693
694
695
696
# File 'ext/evilr/evilr.c', line 690

static VALUE evilr_set_singleton_class(VALUE self, VALUE klass) {
  evilr__check_obj_and_class(self, klass);
  RCLASS_SET_SUPER(evilr__iclass_before_next_class(klass), rb_obj_class(self));
  rb_clear_cache_by_class(klass);
  evilr__make_singleton(self, klass);
  return klass;
}

#swap(other) ⇒ self

Swap the contents of the receiver with other:

a = []
b = {}
a.swap(b) # => {}
a # => {}
b # => []

You cannot swap a Class or Module except with another Class or Module, and you can only swap a Class with a Class and a Module with a Module (no swapping a Class with Module), and you cannot swap immediate values. If an invalid swap attempt is detected, a TypeError is raised.

Returns:

  • (self)


300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'ext/evilr/evilr.c', line 300

static VALUE evilr_swap(VALUE self, VALUE other) {
  char tmp[OBJECT_SIZE];
  evilr__check_immediates(self, other);
  if ((BUILTIN_TYPE(self) == T_MODULE || BUILTIN_TYPE(self) == T_CLASS ||
       BUILTIN_TYPE(other) == T_MODULE || BUILTIN_TYPE(other) == T_CLASS) &&
       BUILTIN_TYPE(self) != BUILTIN_TYPE(other)) {
    rb_raise(rb_eTypeError, "incompatible types used");
  }
  memcpy(tmp, ROBJECT(self), OBJECT_SIZE);
  memcpy(ROBJECT(self), ROBJECT(other), OBJECT_SIZE);
  memcpy(ROBJECT(other), tmp, OBJECT_SIZE);
  return self;
}

#swap_instance_variables(other) ⇒ self

Swaps only the instance variables of the receiver and other. You can only swap the instance variables between two objects that use the internal type number T_OBJECT, or between Classes and Modules. You cannot swap instance variables of immediate values, since they do not have instance variables. Invalid swap attempts will raise TypeError.

Returns:

  • (self)


323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'ext/evilr/evilr.c', line 323

static VALUE evilr_swap_instance_variables(VALUE self, VALUE other) {
#ifndef RUBY19
  struct st_table *tmp;
#endif
  evilr__check_immediates(self, other);

  switch(BUILTIN_TYPE(self)) {
    case T_OBJECT:
      if (BUILTIN_TYPE(other) != T_OBJECT) {
        goto bad_types;
      }
      break;
    case T_MODULE:
    case T_CLASS:
      if (BUILTIN_TYPE(other) != T_MODULE && BUILTIN_TYPE(other) != T_CLASS) {
        goto bad_types;
      }
      break;
    default:
bad_types:
      rb_raise(rb_eTypeError, "incompatible types used");
  }

#ifdef RUBY19
  if (BUILTIN_TYPE(self) == T_MODULE || BUILTIN_TYPE(self) == T_CLASS) {
    struct st_table *tmp;
    tmp = RCLASS_IV_TBL(self);
    RCLASS(self)->ptr->iv_tbl = RCLASS_IV_TBL(other);
    RCLASS(other)->ptr->iv_tbl = tmp;
  } else {
    char tmp[OBJECT_SIZE];
    memcpy(tmp, &(ROBJECT(self)->as), sizeof(ROBJECT(tmp)->as));
    memcpy(&(ROBJECT(self)->as), &(ROBJECT(other)->as), sizeof(ROBJECT(self)->as));
    memcpy(&(ROBJECT(other)->as), tmp, sizeof(ROBJECT(other)->as));
  }
#else
  /* RClass and RObject have iv_tbl at same position in the structure
   * so no funny business is needed */
  tmp = ROBJECT_IVPTR(self);
  ROBJECT(self)->iv_tbl = ROBJECT_IVPTR(other);
  ROBJECT(other)->iv_tbl = tmp;
#endif
  return self;
}

#swap_singleton_class(other) ⇒ self

Swap the singleton classes of the receiver and other. If either the receiver or other is an immediate, a TypeError is raised. If either object does not have a singleton class, an empty singleton class is created for it before swapping. Any modules that extend either object are swapped as well.

Returns:

  • (self)


398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# File 'ext/evilr/evilr.c', line 398

static VALUE evilr_swap_singleton_class(VALUE self, VALUE other) {
  VALUE tmp;

  evilr__check_immediates(self, other);

  /* Create singleton classes to be swapped if they doesn't exist */
  (void)rb_singleton_class(other);
  (void)rb_singleton_class(self);

  tmp = rb_obj_class(other);
  evilr__reparent_singleton_class(other, rb_obj_class(self));
  evilr__reparent_singleton_class(self, tmp);

  tmp = RBASIC_KLASS(self);
  RBASIC_SET_KLASS(self, RBASIC_KLASS(other));
  RBASIC_SET_KLASS(other, tmp);

  /* Attach each singleton class to its object */
  rb_singleton_class_attached(RBASIC_KLASS(self), self);
  rb_singleton_class_attached(RBASIC_KLASS(other), other);

  return self;
}

#unextend(mod) ⇒ Object

Unextends the given module mod from the receiver. If the receiver’s class includes the module, does not uninclude it, so this should not affect any other objects besides the receiver. If mod already extended the object, returns mod, otherwise returns nil. Raises TypeError if mod is not a Module or if the receiver is an immediate.



489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
# File 'ext/evilr/evilr.c', line 489

static VALUE evilr_unextend(VALUE self, VALUE mod) {
  VALUE prev, cur;

  evilr__check_immediates(self, mod);
  evilr__check_type(T_MODULE, mod);

  self = rb_singleton_class(self);
  rb_clear_cache_by_class(self);
  for (prev = self, cur = RCLASS_SUPER(self); cur && BUILTIN_TYPE(cur) != T_CLASS; prev = cur, cur = RCLASS_SUPER(cur)) {
    if (BUILTIN_TYPE(cur) == T_ICLASS && RBASIC_KLASS(cur) == mod) {
      RCLASS_SET_SUPER(prev, RCLASS_SUPER(cur));
      return mod;
    }
  }

  return Qnil;
}

#unfreezeself

Unfreezes the given object. Will raise a SecurityError if $SAFE > 0. Has no effect if the object is not yet frozen.

Returns:

  • (self)


427
428
429
430
431
432
433
# File 'ext/evilr/evilr.c', line 427

static VALUE evilr_unfreeze(VALUE self) {
  if (rb_safe_level() > 0) {
    rb_raise(rb_eSecurityError, "can't unfreeze objects when $SAFE > 0");
  }
  FL_UNSET(self, FL_FREEZE);
  return self;
}