Class: Module
Class Method Summary collapse
-
.load(String) ⇒ Module
Load a module from a string.
Instance Method Summary collapse
-
#dump(limit) ⇒ String
Dump a module to a string.
-
#add_method(id, node) ⇒ Object
Adds the method as an instance method to the given class.
-
#real_superclass ⇒ Class
Return the immediate superclass of a class or module.
Class Method Details
.load(String) ⇒ Module
Load a module from a string.
737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 |
# File 'ext/internal/module/module.c', line 737
static VALUE module_load(VALUE klass, VALUE str)
{
VALUE arr, class_name, metaclass_str, metaclass, superclass_name,
included_modules, class_variables_str, class_variables,
instance_methods_str, instance_methods, flags, module;
if( rb_safe_level() >= 4
|| (rb_safe_level() >= 1 && OBJ_TAINTED(str)))
{
/* no playing with knives in the sandbox */
rb_raise(rb_eSecurityError, "Insecure: can't load module");
}
arr = marshal_load(str);
class_name = rb_ary_pop(arr);
metaclass_str = rb_ary_pop(arr);
superclass_name = rb_ary_pop(arr);
included_modules = rb_ary_pop(arr);
class_variables_str = rb_ary_pop(arr);
instance_methods_str = rb_ary_pop(arr);
flags = rb_ary_pop(arr);
if(RTEST(superclass_name))
{
VALUE superclass;
rb_check_type(superclass_name, T_STRING);
superclass = rb_funcall(
lookup_module_proc,
rb_intern("call"),
1,
superclass_name);
#if RUBY_VERSION_CODE >= 180
/* Can't make subclass of Class on 1.8.x */
module = rb_class_boot(superclass);
rb_define_alloc_func(module, module_instance_allocate);
#else
module = rb_class_new(superclass);
#endif
}
else
{
module = rb_module_new();
}
if(!NIL_P(class_name))
{
VALUE outer_module = rb_funcall(outer_module_proc, rb_intern("call"), 1, class_name);
VALUE module_name = rb_funcall(module_name_proc, rb_intern("call"), 1, class_name);
rb_const_set(outer_module, SYM2ID(module_name), module);
}
RBASIC(module)->flags = NUM2INT(flags);
include_modules(module, included_modules);
class_variables = marshal_load(class_variables_str);
add_class_variables(module, class_variables);
instance_methods = marshal_load(instance_methods_str);
add_methods(module, instance_methods);
metaclass = marshal_load(metaclass_str);
if(RTEST(metaclass))
{
rb_singleton_class_attached(metaclass, module);
RBASIC(module)->klass = metaclass;
}
return module;
}
|
Instance Method Details
#dump(limit) ⇒ String
Dump a module to a string. The module will be dumped along with its instance methods, class variables, names of included modules, name of superclass, its entire metaclass, and the name of the class.
Note that on ruby 1.8 and newer the module is temporarily modified while dumping in order to allow singleton classes to be dumped. To prevent access to the modifed module, Thread.critical is temporarily set, then restored to its original value once dumping is complete. Note also that because YARV does not support Thread.critical, the user must synchronize access to the class with a Mutex in order to prevent accessing the modified class.
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 |
# File 'ext/internal/module/module.c', line 608
static VALUE module_dump(VALUE self, VALUE limit)
{
VALUE flags, instance_methods, class_variables;
VALUE included_modules, superclass, metaclass, arr, str, class_name;
limit = INT2NUM(NUM2INT(limit) - 1);
if(rb_safe_level() >= 4)
{
/* no access to potentially sensitive data from the sandbox */
rb_raise(rb_eSecurityError, "Insecure: can't dump module");
}
flags = INT2NUM(RBASIC(self)->flags);
instance_methods = instance_method_hash(self);
class_variables = class_variable_hash(self);
included_modules = included_modules_list(self);
superclass = superclass_name(self);
arr = rb_ary_new();
if(FL_TEST(self, FL_SINGLETON))
{
metaclass = Qnil;
class_name = Qnil;
}
else
{
metaclass = rb_singleton_class(self);
class_name = rb_class_path(self);
}
rb_ary_push(arr, flags);
rb_ary_push(arr, marshal_dump(instance_methods, limit));
rb_ary_push(arr, marshal_dump(class_variables, limit));
rb_ary_push(arr, included_modules);
rb_ary_push(arr, superclass);
rb_ary_push(arr, marshal_dump(metaclass, limit));
rb_ary_push(arr, class_name);
str = marshal_dump(arr, limit);
#if RUBY_VERSION_CODE > 180
{
VALUE class_restorer = create_class_restorer(self);
rb_iv_set(str, "__class_restorer__", class_restorer);
set_class_restore_state(self);
}
#endif
return str;
}
|
#add_method(id, node) ⇒ Object
Adds the method as an instance method to the given class.
To add a singleton method to a class, add the method to its singleton class.
406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 |
# File 'ext/internal/module/module.c', line 406
static VALUE module_add_method(VALUE klass, VALUE id, VALUE node, VALUE noex)
{
NODE * n = 0;
if(rb_safe_level() >= 2)
{
/* adding a method with the wrong node type can cause a crash */
rb_raise(rb_eSecurityError, "Insecure: can't add method");
}
#if RUBY_VERSION_CODE >= 192
if(rb_obj_is_kind_of(node, rb_cISeq))
{
rb_iseq_t *iseqdat = iseq_check(node);
set_cref_stack(iseqdat, klass, noex);
iseqdat->klass = klass;
iseqdat->defined_method_id = SYM2ID(id);
#ifdef HAVE_RB_ADD_METHOD
rb_add_method(klass, SYM2ID(id), VM_METHOD_TYPE_ISEQ, iseqdat, NUM2INT(noex));
#else
rb_funcall(rb_mRubyVMFrozenCore, rb_intern("core#define_method"), 3, klass, id, node); /* TODO: noex */
#endif
return Qnil;
}
#elif RUBY_VERSION_CODE >= 190
if(rb_obj_is_kind_of(node, rb_cISeq))
{
rb_iseq_t *iseqdat = iseq_check(node);
/* TODO: any restrictions on what kinds of iseqs we can add here? */
set_cref_stack(iseqdat, klass, noex);
iseqdat->klass = klass;
iseqdat->defined_method_id = SYM2ID(id);
n = NEW_METHOD(iseqdat->self, klass, NUM2INT(noex));
goto add_node;
}
#endif
if(!rb_obj_is_kind_of(node, rb_cNode))
{
rb_raise(
rb_eTypeError,
"Expected Node for 2nd parameter, got %s",
rb_class2name(CLASS_OF(n)));
}
Data_Get_Struct(node, NODE, n);
#if RUBY_VERSION_CODE >= 192
rb_raise(rb_eRuntimeError, "Unable to add node on this version of ruby");
#elif RUBY_VERSION_CODE >= 190
if(nd_type(n) != NODE_METHOD)
{
rb_raise(
rb_eTypeError,
"Expected METHOD node, got %s",
rb_class2name(CLASS_OF(n)));
}
{
rb_iseq_t *iseqdat = iseq_check((VALUE)n->nd_body);
set_cref_stack(iseqdat, klass, noex);
iseqdat->klass = klass;
iseqdat->defined_method_id = SYM2ID(id);
n = NEW_METHOD(iseqdat->self, klass, NUM2INT(noex));
}
add_node:
#endif
#if RUBY_VERSION_CODE >= 192
rb_raise(rb_eRuntimeError, "Unable to add node on this version of ruby");
#else
/* TODO: if noex is NOEX_MODFUNC, add this method as a module function
* (that is, both as an instance and singleton method)
*/
rb_add_method(klass, SYM2ID(id), n, NUM2INT(noex));
return Qnil;
#endif
}
|
#real_superclass ⇒ Class
Return the immediate superclass of a class or module. This may be a base class, a singleton class, or a module singleton.
585 586 587 588 589 590 |
# File 'ext/internal/module/module.c', line 585
VALUE module_real_superclass(VALUE self)
{
VALUE super = RCLASS_SUPER(self);
rb_include_module(rb_class_of(super), rb_mKernel);
return super;
}
|