зеркало из https://github.com/github/ruby.git
Add Module.used_refinements
This commit is contained in:
Родитель
5757696e07
Коммит
21ee5341f8
3
NEWS.md
3
NEWS.md
|
@ -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.
|
Note: We're only listing outstanding class updates.
|
||||||
|
|
||||||
|
* Module
|
||||||
|
* Module.used_refinements has been added. [[Feature #14332]]
|
||||||
|
|
||||||
## Stdlib updates
|
## Stdlib updates
|
||||||
|
|
||||||
* The following default gem are updated.
|
* The following default gem are updated.
|
||||||
|
|
53
eval.c
53
eval.c
|
@ -1510,6 +1510,57 @@ rb_mod_s_used_modules(VALUE _)
|
||||||
return rb_funcall(ary, rb_intern("uniq"), 0);
|
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 {
|
struct refinement_import_methods_arg {
|
||||||
rb_cref_t *cref;
|
rb_cref_t *cref;
|
||||||
VALUE refinement;
|
VALUE refinement;
|
||||||
|
@ -1944,6 +1995,8 @@ Init_eval(void)
|
||||||
rb_define_private_method(rb_cModule, "using", mod_using, 1);
|
rb_define_private_method(rb_cModule, "using", mod_using, 1);
|
||||||
rb_define_singleton_method(rb_cModule, "used_modules",
|
rb_define_singleton_method(rb_cModule, "used_modules",
|
||||||
rb_mod_s_used_modules, 0);
|
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_undef_method(rb_cClass, "refine");
|
||||||
rb_define_private_method(rb_cRefinement, "import_methods", refinement_import_methods, -1);
|
rb_define_private_method(rb_cRefinement, "import_methods", refinement_import_methods, -1);
|
||||||
|
|
||||||
|
|
|
@ -1687,6 +1687,8 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
refine Object do
|
refine Object do
|
||||||
def in_ref_a
|
def in_ref_a
|
||||||
end
|
end
|
||||||
|
|
||||||
|
RefA.const_set(:REF, self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1694,6 +1696,8 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
refine Object do
|
refine Object do
|
||||||
def in_ref_b
|
def in_ref_b
|
||||||
end
|
end
|
||||||
|
|
||||||
|
RefB.const_set(:REF, self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1703,23 +1707,28 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
refine Object do
|
refine Object do
|
||||||
def in_ref_c
|
def in_ref_c
|
||||||
end
|
end
|
||||||
|
|
||||||
|
RefC.const_set(:REF, self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module Foo
|
module Foo
|
||||||
using RefB
|
using RefB
|
||||||
USED_MODS = Module.used_modules
|
USED_MODS = Module.used_modules
|
||||||
|
USED_REFS = Module.used_refinements
|
||||||
end
|
end
|
||||||
|
|
||||||
module Bar
|
module Bar
|
||||||
using RefC
|
using RefC
|
||||||
USED_MODS = Module.used_modules
|
USED_MODS = Module.used_modules
|
||||||
|
USED_REFS = Module.used_refinements
|
||||||
end
|
end
|
||||||
|
|
||||||
module Combined
|
module Combined
|
||||||
using RefA
|
using RefA
|
||||||
using RefB
|
using RefB
|
||||||
USED_MODS = Module.used_modules
|
USED_MODS = Module.used_modules
|
||||||
|
USED_REFS = Module.used_refinements
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1731,6 +1740,14 @@ class TestRefinement < Test::Unit::TestCase
|
||||||
assert_equal [ref::RefB, ref::RefA], ref::Combined::USED_MODS
|
assert_equal [ref::RefB, ref::RefA], ref::Combined::USED_MODS
|
||||||
end
|
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
|
def test_warn_setconst_in_refinmenet
|
||||||
bug10103 = '[ruby-core:64143] [Bug #10103]'
|
bug10103 = '[ruby-core:64143] [Bug #10103]'
|
||||||
warnings = [
|
warnings = [
|
||||||
|
|
Загрузка…
Ссылка в новой задаче