Skip to content

Commit

Permalink
* eval.c (rb_mod_refinements): new method Module#refinements.
Browse files Browse the repository at this point in the history
* test/ruby/test_refinement.rb: add new tests for the above changes.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37118 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
shugo committed Oct 8, 2012
1 parent e028d3d commit 1bb89a6
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 0 deletions.
6 changes: 6 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Mon Oct 8 23:55:41 2012 Shugo Maeda <[email protected]>

* eval.c (rb_mod_refinements): new method Module#refinements.

* test/ruby/test_refinement.rb: add new tests for the above changes.

Mon Oct 8 23:02:19 2012 Shugo Maeda <[email protected]>

* eval.c, gc.c, iseq.c, node.h, vm_insnhelper.c, vm_insnhelper.h,
Expand Down
32 changes: 32 additions & 0 deletions eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -1226,6 +1226,37 @@ rb_mod_refine(VALUE module, VALUE klass)
return mod;
}

static int
refinements_i(VALUE key, VALUE value, VALUE arg)
{
rb_hash_aset(arg, key, value);
return ST_CONTINUE;
}

/*
* call-seq:
* refinements -> hash
*
* Returns refinements in the receiver as a hash table, whose key is a
* refined class and whose value is a refinement module.
*/

static VALUE
rb_mod_refinements(VALUE module)
{
ID id_refinements;
VALUE refinements, result;

CONST_ID(id_refinements, "__refinements__");
refinements = rb_attr_get(module, id_refinements);
if (NIL_P(refinements)) {
return rb_hash_new();
}
result = rb_hash_new();
rb_hash_foreach(refinements, refinements_i, result);
return result;
}

void
rb_obj_call_init(VALUE obj, int argc, VALUE *argv)
{
Expand Down Expand Up @@ -1524,6 +1555,7 @@ Init_eval(void)
rb_define_private_method(rb_cModule, "prepend", rb_mod_prepend, -1);
rb_define_private_method(rb_cModule, "using", rb_mod_using, 1);
rb_define_private_method(rb_cModule, "refine", rb_mod_refine, 1);
rb_define_method(rb_cModule, "refinements", rb_mod_refinements, 0);

rb_undef_method(rb_cClass, "module_function");

Expand Down
65 changes: 65 additions & 0 deletions test/ruby/test_refinement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -455,4 +455,69 @@ def test_module_using_class
end
end
end

def test_refinements_empty
m = Module.new
assert(m.refinements.empty?)
end

def test_refinements_one
c = Class.new
c_ext = nil
m = Module.new {
refine c do
c_ext = self
end
}
assert_equal({c => c_ext}, m.refinements)
end

def test_refinements_two
c1 = Class.new
c1_ext = nil
c2 = Class.new
c2_ext = nil
m = Module.new {
refine c1 do
c1_ext = self
end

refine c2 do
c2_ext = self
end
}
assert_equal({c1 => c1_ext, c2 => c2_ext}, m.refinements)
end

def test_refinements_duplicate_refine
c = Class.new
c_ext = nil
m = Module.new {
refine c do
c_ext = self
end
refine c do
end
}
assert_equal({c => c_ext}, m.refinements)
end

def test_refinements_no_recursion
c1 = Class.new
c1_ext = nil
m1 = Module.new {
refine c1 do
c1_ext = self
end
}
c2 = Class.new
c2_ext = nil
m2 = Module.new {
using m1
refine c2 do
c2_ext = self
end
}
assert_equal({c2 => c2_ext}, m2.refinements)
end
end

0 comments on commit 1bb89a6

Please sign in to comment.