* eval.c (rb_mod_s_used_refinements): new method
Module.used_refinements. based on the patch by Charlie Somerville. [Feature #7418] [ruby-core:49805] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56094 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
d6e4975eaf
commit
4a660c72a3
@ -1,3 +1,9 @@
|
|||||||
|
Thu Sep 8 01:12:47 2016 Shugo Maeda <shugo@ruby-lang.org>
|
||||||
|
|
||||||
|
* eval.c (rb_mod_s_used_refinements): new method
|
||||||
|
Module.used_refinements. based on the patch by Charlie
|
||||||
|
Somerville. [Feature #7418] [ruby-core:49805]
|
||||||
|
|
||||||
Wed Sep 7 17:50:38 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Wed Sep 7 17:50:38 2016 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* include/ruby/util.h (setenv): remove POSIX-noncompliant
|
* include/ruby/util.h (setenv): remove POSIX-noncompliant
|
||||||
|
55
eval.c
55
eval.c
@ -1311,6 +1311,59 @@ mod_using(VALUE self, VALUE module)
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
used_refinements_i(VALUE _, VALUE mod, VALUE ary)
|
||||||
|
{
|
||||||
|
ID id_defined_at;
|
||||||
|
CONST_ID(id_defined_at, "__defined_at__");
|
||||||
|
while (FL_TEST(rb_class_of(mod), RMODULE_IS_REFINEMENT)) {
|
||||||
|
rb_ary_push(ary, rb_attr_get(rb_class_of(mod), id_defined_at));
|
||||||
|
mod = RCLASS_SUPER(mod);
|
||||||
|
}
|
||||||
|
return ST_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* used_refinements -> array
|
||||||
|
*
|
||||||
|
* Returns an array of all active refinements 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>
|
||||||
|
*
|
||||||
|
* [B, A]
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
rb_mod_s_used_refinements(void)
|
||||||
|
{
|
||||||
|
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 rb_funcall(ary, rb_intern("uniq"), 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_obj_call_init(VALUE obj, int argc, const VALUE *argv)
|
rb_obj_call_init(VALUE obj, int argc, const VALUE *argv)
|
||||||
{
|
{
|
||||||
@ -1645,6 +1698,8 @@ Init_eval(void)
|
|||||||
rb_define_private_method(rb_cModule, "prepend_features", rb_mod_prepend_features, 1);
|
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, "refine", rb_mod_refine, 1);
|
||||||
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_refinements",
|
||||||
|
rb_mod_s_used_refinements, 0);
|
||||||
rb_undef_method(rb_cClass, "refine");
|
rb_undef_method(rb_cClass, "refine");
|
||||||
|
|
||||||
rb_undef_method(rb_cClass, "module_function");
|
rb_undef_method(rb_cClass, "module_function");
|
||||||
|
@ -1624,6 +1624,55 @@ class TestRefinement < Test::Unit::TestCase
|
|||||||
MethodMissing.call_undefined_method
|
MethodMissing.call_undefined_method
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
module VisibleRefinements
|
||||||
|
module RefA
|
||||||
|
refine Object do
|
||||||
|
def in_ref_a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module RefB
|
||||||
|
refine Object do
|
||||||
|
def in_ref_b
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module RefC
|
||||||
|
using RefA
|
||||||
|
|
||||||
|
refine Object do
|
||||||
|
def in_ref_c
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Foo
|
||||||
|
using RefB
|
||||||
|
USED_REFS = Module.used_refinements
|
||||||
|
end
|
||||||
|
|
||||||
|
module Bar
|
||||||
|
using RefC
|
||||||
|
USED_REFS = Module.used_refinements
|
||||||
|
end
|
||||||
|
|
||||||
|
module Combined
|
||||||
|
using RefA
|
||||||
|
using RefB
|
||||||
|
USED_REFS = Module.used_refinements
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_used_refinements
|
||||||
|
ref = VisibleRefinements
|
||||||
|
assert_equal [], Module.used_refinements
|
||||||
|
assert_equal [ref::RefB], ref::Foo::USED_REFS
|
||||||
|
assert_equal [ref::RefC], ref::Bar::USED_REFS
|
||||||
|
assert_equal [ref::RefB, ref::RefA], ref::Combined::USED_REFS
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user