prevent-circular-using.patch
eval.c | ||
---|---|---|
1130 | 1130 |
rb_hash_foreach(refinements, using_refinement, (VALUE) cref); |
1131 | 1131 |
} |
1132 | 1132 | |
1133 | ||
1134 |
static int |
|
1135 |
check_circular_using(VALUE mod, VALUE _, VALUE search) |
|
1136 |
{ |
|
1137 |
VALUE using_modules; |
|
1138 |
ID id_using_modules; |
|
1139 |
CONST_ID(id_using_modules, "__using_modules__"); |
|
1140 | ||
1141 |
if(mod == search) { |
|
1142 |
rb_raise(rb_eTypeError, "circular using is not allowed"); |
|
1143 |
} |
|
1144 | ||
1145 |
using_modules = rb_attr_get(mod, id_using_modules); |
|
1146 |
if (!NIL_P(using_modules)) { |
|
1147 |
rb_hash_foreach(using_modules, check_circular_using, search); |
|
1148 |
} |
|
1149 | ||
1150 |
return ST_CONTINUE; |
|
1151 |
} |
|
1152 | ||
1133 | 1153 |
/* |
1134 | 1154 |
* call-seq: |
1135 | 1155 |
* using(module) -> self |
... | ... | |
1145 | 1165 |
VALUE using_modules; |
1146 | 1166 | |
1147 | 1167 |
Check_Type(module, T_MODULE); |
1168 |
check_circular_using(module, 0, self); |
|
1148 | 1169 |
CONST_ID(id_using_modules, "__using_modules__"); |
1149 | 1170 |
using_modules = rb_attr_get(self, id_using_modules); |
1150 | 1171 |
if (NIL_P(using_modules)) { |
test/ruby/test_refinement.rb | ||
---|---|---|
685 | 685 |
assert_equal("#<refinement:#{c.inspect}@#{m.inspect}>", |
686 | 686 |
m.refinements[c].inspect) |
687 | 687 |
end |
688 | ||
689 |
def test_circular_using_is_not_allowed |
|
690 |
a = Module.new |
|
691 |
b = Module.new |
|
692 | ||
693 |
assert_raise TypeError do |
|
694 |
a.module_eval do |
|
695 |
using a |
|
696 |
end |
|
697 |
end |
|
698 | ||
699 |
b.module_eval do |
|
700 |
using a |
|
701 |
end |
|
702 | ||
703 |
assert_raise TypeError do |
|
704 |
a.module_eval do |
|
705 |
using b |
|
706 |
end |
|
707 |
end |
|
708 |
end |
|
688 | 709 |
end |