/*
* call-seq:
* module.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.
*/
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(ruby_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;
}