Project

General

Profile

Feature #7418 ยป used_refinements.patch

Anonymous, 11/21/2012 08:16 PM

View differences:

eval.c
return result;
}
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
*
* module C
* using B
*
* refine Object do
* end
* end
*
* using A
* p used_refinements
*
* C.module_eval { p used_refinements }
*
* <em>produces:</em>
*
* [A]
* [C, B, A]
*/
static VALUE
rb_f_used_refinements(void)
{
NODE *cref = rb_vm_cref();
VALUE ary = rb_ary_new();
while(cref) {
if(!NIL_P(cref->nd_refinements)) {
rb_hash_foreach(cref->nd_refinements, used_refinements_i, ary);
}
cref = cref->nd_next;
}
return rb_funcall(ary, rb_intern("uniq"), 0);
}
void
rb_obj_call_init(VALUE obj, int argc, VALUE *argv)
{
......
rb_define_global_function("__method__", rb_f_method_name, 0);
rb_define_global_function("__callee__", rb_f_callee_name, 0);
rb_define_global_function("__dir__", f_current_dirname, 0);
rb_define_global_function("used_refinements", rb_f_used_refinements, 0);
rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
test/ruby/test_refinement.rb
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
end
module Bar
using RefC
end
module Combined
using Foo
using Bar
end
end
def test_used_refinements
ref = VisibleRefinements
assert_equal [], used_refinements
assert_equal [ref::RefB], ref::Foo.module_eval { used_refinements }
assert_equal [ref::RefC, ref::RefA], ref::Bar.module_eval { used_refinements }
assert_equal [ref::RefC, ref::RefA, ref::RefB], ref::Combined.module_eval { used_refinements }
end
end
    (1-1/1)