* variable.c (rb_mod_class_variables): return inherited variables
except when the optional argument is set to false. [ruby-dev:44034] [Bug #4971] * variable.c (rb_mod_constants): fix typo in documentation. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
0e60c71038
commit
1f03c90dbf
@ -1,3 +1,11 @@
|
|||||||
|
Thu Jul 19 15:38:35 2012 Shugo Maeda <shugo@ruby-lang.org>
|
||||||
|
|
||||||
|
* variable.c (rb_mod_class_variables): return inherited variables
|
||||||
|
except when the optional argument is set to false.
|
||||||
|
[ruby-dev:44034] [Bug #4971]
|
||||||
|
|
||||||
|
* variable.c (rb_mod_constants): fix typo in documentation.
|
||||||
|
|
||||||
Thu Jul 19 14:30:43 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Thu Jul 19 14:30:43 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* internal.h: move mark function declarations that should be private.
|
* internal.h: move mark function declarations that should be private.
|
||||||
|
@ -886,7 +886,7 @@ VALUE rb_cvar_get(VALUE, ID);
|
|||||||
void rb_cv_set(VALUE, const char*, VALUE);
|
void rb_cv_set(VALUE, const char*, VALUE);
|
||||||
VALUE rb_cv_get(VALUE, const char*);
|
VALUE rb_cv_get(VALUE, const char*);
|
||||||
void rb_define_class_variable(VALUE, const char*, VALUE);
|
void rb_define_class_variable(VALUE, const char*, VALUE);
|
||||||
VALUE rb_mod_class_variables(VALUE);
|
VALUE rb_mod_class_variables(int, VALUE*, VALUE);
|
||||||
VALUE rb_mod_remove_cvar(VALUE, VALUE);
|
VALUE rb_mod_remove_cvar(VALUE, VALUE);
|
||||||
|
|
||||||
ID rb_frame_callee(void);
|
ID rb_frame_callee(void);
|
||||||
|
2
object.c
2
object.c
@ -2979,7 +2979,7 @@ Init_Object(void)
|
|||||||
rb_define_method(rb_cModule, "const_missing",
|
rb_define_method(rb_cModule, "const_missing",
|
||||||
rb_mod_const_missing, 1); /* in variable.c */
|
rb_mod_const_missing, 1); /* in variable.c */
|
||||||
rb_define_method(rb_cModule, "class_variables",
|
rb_define_method(rb_cModule, "class_variables",
|
||||||
rb_mod_class_variables, 0); /* in variable.c */
|
rb_mod_class_variables, -1); /* in variable.c */
|
||||||
rb_define_method(rb_cModule, "remove_class_variable",
|
rb_define_method(rb_cModule, "remove_class_variable",
|
||||||
rb_mod_remove_cvar, 1); /* in variable.c */
|
rb_mod_remove_cvar, 1); /* in variable.c */
|
||||||
rb_define_method(rb_cModule, "class_variable_get", rb_mod_cvar_get, 1);
|
rb_define_method(rb_cModule, "class_variable_get", rb_mod_cvar_get, 1);
|
||||||
|
@ -1356,4 +1356,16 @@ class TestModule < Test::Unit::TestCase
|
|||||||
assert_equal([:m1], Class.new{ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
|
assert_equal([:m1], Class.new{ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
|
||||||
assert_equal([:m1], Class.new(Class.new{def m2;end}){ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
|
assert_equal([:m1], Class.new(Class.new{def m2;end}){ prepend Module.new; def m1; end }.instance_methods(false), bug6660)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_class_variables
|
||||||
|
m = Module.new
|
||||||
|
m.class_variable_set(:@@foo, 1)
|
||||||
|
m2 = Module.new
|
||||||
|
m2.send(:include, m)
|
||||||
|
m2.class_variable_set(:@@bar, 2)
|
||||||
|
assert_equal([:@@foo], m.class_variables)
|
||||||
|
assert_equal([:@@bar, :@@foo], m2.class_variables)
|
||||||
|
assert_equal([:@@bar, :@@foo], m2.class_variables(true))
|
||||||
|
assert_equal([:@@bar], m2.class_variables(false))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
83
variable.c
83
variable.c
@ -1939,7 +1939,7 @@ rb_const_list(void *data)
|
|||||||
*
|
*
|
||||||
* Returns an array of the names of the constants accessible in
|
* Returns an array of the names of the constants accessible in
|
||||||
* <i>mod</i>. This includes the names of constants in any included
|
* <i>mod</i>. This includes the names of constants in any included
|
||||||
* modules (example at start of section), unless the <i>all</i>
|
* modules (example at start of section), unless the <i>inherit</i>
|
||||||
* parameter is set to <code>false</code>.
|
* parameter is set to <code>false</code>.
|
||||||
*
|
*
|
||||||
* IO.constants.include?(:SYNC) #=> true
|
* IO.constants.include?(:SYNC) #=> true
|
||||||
@ -2323,22 +2323,71 @@ static int
|
|||||||
cv_i(st_data_t k, st_data_t v, st_data_t a)
|
cv_i(st_data_t k, st_data_t v, st_data_t a)
|
||||||
{
|
{
|
||||||
ID key = (ID)k;
|
ID key = (ID)k;
|
||||||
VALUE ary = (VALUE)a;
|
st_table *tbl = (st_table *)a;
|
||||||
|
|
||||||
if (rb_is_class_id(key)) {
|
if (rb_is_class_id(key)) {
|
||||||
VALUE kval = ID2SYM(key);
|
if (!st_lookup(tbl, (st_data_t)key, 0)) {
|
||||||
if (!rb_ary_includes(ary, kval)) {
|
st_insert(tbl, (st_data_t)key, 0);
|
||||||
rb_ary_push(ary, kval);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ST_CONTINUE;
|
return ST_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
mod_cvar_at(VALUE mod, void *data)
|
||||||
|
{
|
||||||
|
st_table *tbl = data;
|
||||||
|
if (!tbl) {
|
||||||
|
tbl = st_init_numtable();
|
||||||
|
}
|
||||||
|
if (RCLASS_IV_TBL(mod)) {
|
||||||
|
st_foreach_safe(RCLASS_IV_TBL(mod), cv_i, (st_data_t)tbl);
|
||||||
|
}
|
||||||
|
return tbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
mod_cvar_of(VALUE mod, void *data)
|
||||||
|
{
|
||||||
|
VALUE tmp = mod;
|
||||||
|
for (;;) {
|
||||||
|
data = mod_cvar_at(tmp, data);
|
||||||
|
tmp = RCLASS_SUPER(tmp);
|
||||||
|
if (!tmp) break;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
cv_list_i(st_data_t key, st_data_t value, VALUE ary)
|
||||||
|
{
|
||||||
|
ID sym = (ID)key;
|
||||||
|
rb_ary_push(ary, ID2SYM(sym));
|
||||||
|
return ST_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
cvar_list(void *data)
|
||||||
|
{
|
||||||
|
st_table *tbl = data;
|
||||||
|
VALUE ary;
|
||||||
|
|
||||||
|
if (!tbl) return rb_ary_new2(0);
|
||||||
|
ary = rb_ary_new2(tbl->num_entries);
|
||||||
|
st_foreach_safe(tbl, cv_list_i, ary);
|
||||||
|
st_free_table(tbl);
|
||||||
|
|
||||||
|
return ary;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* mod.class_variables -> array
|
* mod.class_variables(inherit=true) -> array
|
||||||
*
|
*
|
||||||
* Returns an array of the names of class variables in <i>mod</i>.
|
* Returns an array of the names of class variables in <i>mod</i>.
|
||||||
|
* This includes the names of class variables in any included
|
||||||
|
* modules, unless the <i>inherit</i> parameter is set to
|
||||||
|
* <code>false</code>.
|
||||||
*
|
*
|
||||||
* class One
|
* class One
|
||||||
* @@var1 = 1
|
* @@var1 = 1
|
||||||
@ -2347,18 +2396,28 @@ cv_i(st_data_t k, st_data_t v, st_data_t a)
|
|||||||
* @@var2 = 2
|
* @@var2 = 2
|
||||||
* end
|
* end
|
||||||
* One.class_variables #=> [:@@var1]
|
* One.class_variables #=> [:@@var1]
|
||||||
* Two.class_variables #=> [:@@var2]
|
* Two.class_variables #=> [:@@var2, :@@var1]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_mod_class_variables(VALUE obj)
|
rb_mod_class_variables(int argc, VALUE *argv, VALUE mod)
|
||||||
{
|
{
|
||||||
VALUE ary = rb_ary_new();
|
VALUE inherit;
|
||||||
|
st_table *tbl;
|
||||||
|
|
||||||
if (RCLASS_IV_TBL(obj)) {
|
if (argc == 0) {
|
||||||
st_foreach_safe(RCLASS_IV_TBL(obj), cv_i, (st_data_t)ary);
|
inherit = Qtrue;
|
||||||
}
|
}
|
||||||
return ary;
|
else {
|
||||||
|
rb_scan_args(argc, argv, "01", &inherit);
|
||||||
|
}
|
||||||
|
if (RTEST(inherit)) {
|
||||||
|
tbl = mod_cvar_of(mod, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tbl = mod_cvar_at(mod, 0);
|
||||||
|
}
|
||||||
|
return cvar_list(tbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user