зеркало из https://github.com/github/ruby.git
Add Module#refinements and Refinement#refined_class [Feature #12737]
This commit is contained in:
Родитель
21ee5341f8
Коммит
54198c7b97
4
NEWS.md
4
NEWS.md
|
@ -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
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 = [
|
||||
|
|
Загрузка…
Ссылка в новой задаче