Add Module#refinements and Refinement#refined_class [Feature #12737]

This commit is contained in:
Shugo Maeda 2022-01-05 17:47:29 +09:00
Родитель 21ee5341f8
Коммит 54198c7b97
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 2DFE34085E97CE47
3 изменённых файлов: 76 добавлений и 1 удалений

Просмотреть файл

@ -28,6 +28,10 @@ Note: We're only listing outstanding class updates.
* Module
* Module.used_refinements has been added. [[Feature #14332]]
* Module#refinements has been added. [[Feature #12737]]
* Refinement
* Refinement#refined_class has been added. [[Feature #12737]]
## Stdlib updates

44
eval.c
Просмотреть файл

@ -1322,7 +1322,12 @@ rb_using_module(const rb_cref_t *cref, VALUE module)
rb_clear_method_cache_all();
}
/*! \private */
/*
* call-seq:
* refined_class -> class
*
* Return the class refined by the receiver.
*/
VALUE
rb_refinement_module_get_refined_class(VALUE module)
{
@ -1457,6 +1462,41 @@ mod_using(VALUE self, VALUE module)
return self;
}
/*
* call-seq:
* refinements -> array
*
* Returns an array of modules defined within the receiver.
*
* module A
* refine Integer do
* end
*
* refine String do
* end
* end
*
* p A.refinements
*
* <em>produces:</em>
*
* [#<refinement:Integer@A>, #<refinement:String@A>]
*/
static VALUE
mod_refinements(VALUE self)
{
ID id_refinements;
VALUE refinements;
CONST_ID(id_refinements, "__refinements__");
refinements = rb_attr_get(self, id_refinements);
if (NIL_P(refinements)) {
return rb_ary_new();
}
return rb_hash_values(refinements);
}
static int
used_modules_i(VALUE _, VALUE mod, VALUE ary)
{
@ -1993,12 +2033,14 @@ Init_eval(void)
rb_define_private_method(rb_cModule, "prepend_features", rb_mod_prepend_features, 1);
rb_define_private_method(rb_cModule, "refine", rb_mod_refine, 1);
rb_define_private_method(rb_cModule, "using", mod_using, 1);
rb_define_method(rb_cModule, "refinements", mod_refinements, 0);
rb_define_singleton_method(rb_cModule, "used_modules",
rb_mod_s_used_modules, 0);
rb_define_singleton_method(rb_cModule, "used_refinements",
rb_mod_s_used_refinements, 0);
rb_undef_method(rb_cClass, "refine");
rb_define_private_method(rb_cRefinement, "import_methods", refinement_import_methods, -1);
rb_define_method(rb_cRefinement, "refined_class", rb_refinement_module_get_refined_class, 0);
rb_undef_method(rb_cClass, "module_function");

Просмотреть файл

@ -1748,6 +1748,35 @@ class TestRefinement < Test::Unit::TestCase
assert_equal [ref::RefB::REF, ref::RefA::REF], ref::Combined::USED_REFS
end
def test_refinements
int_refinement = nil
str_refinement = nil
m = Module.new {
refine Integer do
int_refinement = self
end
refine String do
str_refinement = self
end
}
assert_equal([int_refinement, str_refinement], m.refinements)
end
def test_refined_class
refinements = Module.new {
refine Integer do
int_refinement = self
end
refine String do
str_refinement = self
end
}.refinements
assert_equal(Integer, refinements[0].refined_class)
assert_equal(String, refinements[1].refined_class)
end
def test_warn_setconst_in_refinmenet
bug10103 = '[ruby-core:64143] [Bug #10103]'
warnings = [