mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
check object type before retrieving instance variabls; close #311
This commit is contained in:
@@ -49,6 +49,7 @@ int mrb_const_defined_at(mrb_state *mrb, struct RClass *klass, mrb_sym id);
|
||||
mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self);
|
||||
mrb_value mrb_gv_get(mrb_state *mrb, mrb_sym sym);
|
||||
void mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value val);
|
||||
mrb_value mrb_obj_instance_variables(mrb_state*, mrb_value);
|
||||
|
||||
/* GC functions */
|
||||
void mrb_gc_mark_gv(mrb_state*);
|
||||
|
||||
@@ -708,46 +708,6 @@ mrb_obj_ivar_set(mrb_state *mrb, mrb_value self)
|
||||
return val;
|
||||
}
|
||||
|
||||
/* 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 = RCLASS_IV_TBL(self);
|
||||
khint_t i;
|
||||
const char* p;
|
||||
|
||||
ary = mrb_ary_new(mrb);
|
||||
if (h) {
|
||||
for (i=0;i<kh_end(h);i++) {
|
||||
if (kh_exist(h, i)) {
|
||||
p = mrb_sym2name(mrb, kh_key(h,i));
|
||||
if (*p == '@') {
|
||||
if (mrb_type(kh_value(h, i)) != MRB_TT_UNDEF)
|
||||
mrb_ary_push(mrb, ary, mrb_str_new_cstr(mrb, p));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
||||
/* 15.3.1.3.24 */
|
||||
/* 15.3.1.3.26 */
|
||||
/*
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user