This commit is contained in:
Shugo Maeda 2022-01-05 16:58:23 +09:00
Родитель 5757696e07
Коммит 21ee5341f8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 2DFE34085E97CE47
3 изменённых файлов: 73 добавлений и 0 удалений

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

@ -26,6 +26,9 @@ Note that each entry is kept to a minimum, see links for details.
Note: We're only listing outstanding class updates.
* Module
* Module.used_refinements has been added. [[Feature #14332]]
## Stdlib updates
* The following default gem are updated.

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

@ -1510,6 +1510,57 @@ rb_mod_s_used_modules(VALUE _)
return rb_funcall(ary, rb_intern("uniq"), 0);
}
static int
used_refinements_i(VALUE _, VALUE mod, VALUE ary)
{
while (FL_TEST(rb_class_of(mod), RMODULE_IS_REFINEMENT)) {
rb_ary_push(ary, rb_class_of(mod));
mod = RCLASS_SUPER(mod);
}
return ST_CONTINUE;
}
/*
* call-seq:
* used_refinements -> array
*
* Returns an array of all modules used in the current scope. The ordering
* of modules in the resulting array is not defined.
*
* module A
* refine Object do
* end
* end
*
* module B
* refine Object do
* end
* end
*
* using A
* using B
* p Module.used_refinements
*
* <em>produces:</em>
*
* [#<refinement:Object@B>, #<refinement:Object@A>]
*/
static VALUE
rb_mod_s_used_refinements(VALUE _)
{
const rb_cref_t *cref = rb_vm_cref();
VALUE ary = rb_ary_new();
while (cref) {
if (!NIL_P(CREF_REFINEMENTS(cref))) {
rb_hash_foreach(CREF_REFINEMENTS(cref), used_refinements_i, ary);
}
cref = CREF_NEXT(cref);
}
return ary;
}
struct refinement_import_methods_arg {
rb_cref_t *cref;
VALUE refinement;
@ -1944,6 +1995,8 @@ Init_eval(void)
rb_define_private_method(rb_cModule, "using", mod_using, 1);
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);

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

@ -1687,6 +1687,8 @@ class TestRefinement < Test::Unit::TestCase
refine Object do
def in_ref_a
end
RefA.const_set(:REF, self)
end
end
@ -1694,6 +1696,8 @@ class TestRefinement < Test::Unit::TestCase
refine Object do
def in_ref_b
end
RefB.const_set(:REF, self)
end
end
@ -1703,23 +1707,28 @@ class TestRefinement < Test::Unit::TestCase
refine Object do
def in_ref_c
end
RefC.const_set(:REF, self)
end
end
module Foo
using RefB
USED_MODS = Module.used_modules
USED_REFS = Module.used_refinements
end
module Bar
using RefC
USED_MODS = Module.used_modules
USED_REFS = Module.used_refinements
end
module Combined
using RefA
using RefB
USED_MODS = Module.used_modules
USED_REFS = Module.used_refinements
end
end
@ -1731,6 +1740,14 @@ class TestRefinement < Test::Unit::TestCase
assert_equal [ref::RefB, ref::RefA], ref::Combined::USED_MODS
end
def test_used_refinements
ref = VisibleRefinements
assert_equal [], Module.used_refinements
assert_equal [ref::RefB::REF], ref::Foo::USED_REFS
assert_equal [ref::RefC::REF], ref::Bar::USED_REFS
assert_equal [ref::RefB::REF, ref::RefA::REF], ref::Combined::USED_REFS
end
def test_warn_setconst_in_refinmenet
bug10103 = '[ruby-core:64143] [Bug #10103]'
warnings = [