diff options
| author | Yukihiro Matsumoto <[email protected]> | 2012-06-23 10:40:17 +0900 |
|---|---|---|
| committer | Yukihiro Matsumoto <[email protected]> | 2012-06-23 10:40:17 +0900 |
| commit | 1fa63930fd072847d24ffe9c20a57109c41387ec (patch) | |
| tree | d19ad4a48db0934d09cf1dababec2a4ed27f53a0 /src/variable.c | |
| parent | 2d781f5c1da6f627d9b4d3c2c7e9444108e09221 (diff) | |
| download | mruby-1fa63930fd072847d24ffe9c20a57109c41387ec.tar.gz mruby-1fa63930fd072847d24ffe9c20a57109c41387ec.zip | |
check object type before retrieving instance variabls; close #311
Diffstat (limited to 'src/variable.c')
| -rw-r--r-- | src/variable.c | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/src/variable.c b/src/variable.c index 051c971d6..e785d56b7 100644 --- a/src/variable.c +++ b/src/variable.c @@ -185,6 +185,50 @@ mrb_vm_iv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) mrb_iv_set(mrb, mrb->stack[0], sym, v); } +/* 15.3.1.3.23 */ +/* + * call-seq: + * obj.instance_variables -> array + * + * Returns an array of instance variable names for the receiver. Note + * that simply defining an accessor does not create the corresponding + * instance variable. + * + * class Fred + * attr_accessor :a1 + * def initialize + * @iv = 3 + * end + * end + * Fred.new.instance_variables #=> [:@iv] + */ +mrb_value +mrb_obj_instance_variables(mrb_state *mrb, mrb_value self) +{ + mrb_value ary; + kh_iv_t *h; + khint_t i; + int len; + const char* p; + + ary = mrb_ary_new(mrb); + if (obj_iv_p(self)) { + h = ROBJECT_IVPTR(self); + if (h) { + for (i=0;i<kh_end(h);i++) { + if (kh_exist(h, i)) { + p = mrb_sym2name_len(mrb, kh_key(h,i), &len); + if (len > 1 && *p == '@') { + if (mrb_type(kh_value(h, i)) != MRB_TT_UNDEF) + mrb_ary_push(mrb, ary, mrb_str_new(mrb, p, len)); + } + } + } + } + } + return ary; +} + mrb_value mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym) { |
