mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
namespace on read
This commit is contained in:
parent
49742414f6
commit
382645d440
86 changed files with 5850 additions and 702 deletions
80
eval.c
80
eval.c
|
@ -1192,6 +1192,8 @@ rb_mod_append_features(VALUE module, VALUE include)
|
|||
return module;
|
||||
}
|
||||
|
||||
static VALUE refinement_import_methods(int argc, VALUE *argv, VALUE refinement);
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* include(module, ...) -> self
|
||||
|
@ -1345,9 +1347,9 @@ rb_using_refinement(rb_cref_t *cref, VALUE klass, VALUE module)
|
|||
}
|
||||
superclass = refinement_superclass(superclass);
|
||||
c = iclass = rb_include_class_new(module, superclass);
|
||||
RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
|
||||
RCLASS_SET_REFINED_CLASS(c, klass);
|
||||
|
||||
RCLASS_M_TBL(c) = RCLASS_M_TBL(module);
|
||||
RCLASS_WRITE_M_TBL(c, RCLASS_M_TBL(module));
|
||||
|
||||
rb_hash_aset(CREF_REFINEMENTS(cref), klass, iclass);
|
||||
}
|
||||
|
@ -1402,6 +1404,12 @@ rb_using_module(const rb_cref_t *cref, VALUE module)
|
|||
rb_clear_all_refinement_method_cache();
|
||||
}
|
||||
|
||||
void
|
||||
rb_vm_using_module(VALUE module)
|
||||
{
|
||||
rb_using_module(rb_vm_cref_replace_with_duplicated_cref(), module);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* target -> class_or_module
|
||||
|
@ -1442,43 +1450,24 @@ add_activated_refinement(VALUE activated_refinements,
|
|||
}
|
||||
superclass = refinement_superclass(superclass);
|
||||
c = iclass = rb_include_class_new(refinement, superclass);
|
||||
RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
|
||||
RCLASS_SET_REFINED_CLASS(c, klass);
|
||||
refinement = RCLASS_SUPER(refinement);
|
||||
while (refinement && refinement != klass) {
|
||||
c = RCLASS_SET_SUPER(c, rb_include_class_new(refinement, RCLASS_SUPER(c)));
|
||||
RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
|
||||
c = rb_class_set_super(c, rb_include_class_new(refinement, RCLASS_SUPER(c)));
|
||||
RCLASS_SET_REFINED_CLASS(c, klass);
|
||||
refinement = RCLASS_SUPER(refinement);
|
||||
}
|
||||
rb_hash_aset(activated_refinements, klass, iclass);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* refine(mod) { block } -> module
|
||||
*
|
||||
* Refine <i>mod</i> in the receiver.
|
||||
*
|
||||
* Returns a module, where refined methods are defined.
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
rb_mod_refine(VALUE module, VALUE klass)
|
||||
void
|
||||
rb_refinement_setup(struct rb_refinements_data *data, VALUE module, VALUE klass)
|
||||
{
|
||||
VALUE refinement;
|
||||
ID id_refinements, id_activated_refinements,
|
||||
id_refined_class, id_defined_at;
|
||||
VALUE refinements, activated_refinements;
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);
|
||||
|
||||
if (block_handler == VM_BLOCK_HANDLER_NONE) {
|
||||
rb_raise(rb_eArgError, "no block given");
|
||||
}
|
||||
if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
|
||||
rb_raise(rb_eArgError, "can't pass a Proc as a block to Module#refine");
|
||||
}
|
||||
|
||||
ensure_class_or_module(klass);
|
||||
CONST_ID(id_refinements, "__refinements__");
|
||||
refinements = rb_attr_get(module, id_refinements);
|
||||
if (NIL_P(refinements)) {
|
||||
|
@ -1496,7 +1485,7 @@ rb_mod_refine(VALUE module, VALUE klass)
|
|||
if (NIL_P(refinement)) {
|
||||
VALUE superclass = refinement_superclass(klass);
|
||||
refinement = rb_refinement_new();
|
||||
RCLASS_SET_SUPER(refinement, superclass);
|
||||
rb_class_set_super(refinement, superclass);
|
||||
RUBY_ASSERT(BUILTIN_TYPE(refinement) == T_MODULE);
|
||||
FL_SET(refinement, RMODULE_IS_REFINEMENT);
|
||||
CONST_ID(id_refined_class, "__refined_class__");
|
||||
|
@ -1506,8 +1495,41 @@ rb_mod_refine(VALUE module, VALUE klass)
|
|||
rb_hash_aset(refinements, klass, refinement);
|
||||
add_activated_refinement(activated_refinements, klass, refinement);
|
||||
}
|
||||
rb_yield_refine_block(refinement, activated_refinements);
|
||||
return refinement;
|
||||
|
||||
data->refinement = refinement;
|
||||
data->refinements = activated_refinements;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* refine(mod) { block } -> module
|
||||
*
|
||||
* Refine <i>mod</i> in the receiver.
|
||||
*
|
||||
* Returns a module, where refined methods are defined.
|
||||
*/
|
||||
|
||||
static VALUE
|
||||
rb_mod_refine(VALUE module, VALUE klass)
|
||||
{
|
||||
/* module is the receiver of #refine, klass is a module to be refined (`mod` in the doc) */
|
||||
rb_thread_t *th = GET_THREAD();
|
||||
VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);
|
||||
struct rb_refinements_data data;
|
||||
|
||||
if (block_handler == VM_BLOCK_HANDLER_NONE) {
|
||||
rb_raise(rb_eArgError, "no block given");
|
||||
}
|
||||
if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
|
||||
rb_raise(rb_eArgError, "can't pass a Proc as a block to Module#refine");
|
||||
}
|
||||
|
||||
ensure_class_or_module(klass);
|
||||
|
||||
rb_refinement_setup(&data, module, klass);
|
||||
|
||||
rb_yield_refine_block(data.refinement, data.refinements);
|
||||
return data.refinement;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue