/* * call-seq: * obj.respond_to?(symbol, include_private=false) -> true or false * * Returns +true+ if _obj_ responds to the given * method. Private methods are included in the search only if the * optional second parameter evaluates to +true+. * * If the method is not implemented, * as Process.fork on Windows, File.lchmod on GNU/Linux, etc., * false is returned. * * If the method is not defined, <code>respond_to_missing?</code> * method is called and the result is returned. */ mrb_value obj_respond_to(mrb_state *mrb, mrb_value self) { mrb_value *argv; int argc; mrb_value mid, priv; mrb_sym id; mrb_get_args(mrb, "*", &argv, &argc); //mrb_scan_args(argc, argv, "11", &mid, &priv); mid = argv[0]; if (argc > 1) priv = argv[1]; else priv = mrb_nil_value(); id = mrb_to_id(mrb, mid); if (basic_obj_respond_to(mrb, self, id, !RTEST(priv))) return mrb_true_value(); return mrb_false_value(); }
/* * call-seq: * obj.instance_variable_defined?(symbol) -> true or false * * Returns <code>true</code> if the given instance variable is * defined in <i>obj</i>. * * class Fred * def initialize(p1, p2) * @a, @b = p1, p2 * end * end * fred = Fred.new('cat', 99) * fred.instance_variable_defined?(:@a) #=> true * fred.instance_variable_defined?("@b") #=> true * fred.instance_variable_defined?("@c") #=> false */ mrb_value mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self) { mrb_value arg; khiter_t k; kh_iv_t *h = RCLASS_IV_TBL(self); mrb_get_args(mrb, "o", &arg); mrb_sym mid = mrb_to_id(mrb, arg); if (h) { k = kh_get(iv, h, mid); if (k != kh_end(h)) { return mrb_true_value(); } } return mrb_false_value(); }
/* * call-seq: * struct[symbol] -> anObject * struct[fixnum] -> anObject * * Attribute Reference---Returns the value of the instance variable * named by <i>symbol</i>, or indexed (0..length-1) by * <i>fixnum</i>. Will raise <code>NameError</code> if the named * variable does not exist, or <code>IndexError</code> if the index is * out of range. * * Customer = Struct.new(:name, :address, :zip) * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) * * joe["name"] #=> "Joe Smith" * joe[:name] #=> "Joe Smith" * joe[0] #=> "Joe Smith" */ mrb_value mrb_struct_aref_n(mrb_state *mrb, mrb_value s, mrb_value idx) { long i; if (mrb_type(idx) == MRB_TT_STRING || mrb_type(idx) == MRB_TT_SYMBOL) { return mrb_struct_aref_id(mrb, s, mrb_to_id(mrb, idx)); } i = mrb_fixnum(idx); if (i < 0) i = RSTRUCT_LEN(s) + i; if (i < 0) mrb_raise(mrb, E_INDEX_ERROR, "offset %ld too small for struct(size:%ld)", i, RSTRUCT_LEN(s)); if (RSTRUCT_LEN(s) <= i) mrb_raise(mrb, E_INDEX_ERROR, "offset %ld too large for struct(size:%ld)", i, RSTRUCT_LEN(s)); return RSTRUCT_PTR(s)[i]; }
/* * call-seq: * struct[symbol] -> anObject * struct[fixnum] -> anObject * * Attribute Reference---Returns the value of the instance variable * named by <i>symbol</i>, or indexed (0..length-1) by * <i>fixnum</i>. Will raise <code>NameError</code> if the named * variable does not exist, or <code>IndexError</code> if the index is * out of range. * * Customer = Struct.new(:name, :address, :zip) * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345) * * joe["name"] #=> "Joe Smith" * joe[:name] #=> "Joe Smith" * joe[0] #=> "Joe Smith" */ mrb_value mrb_struct_aref_n(mrb_state *mrb, mrb_value s, mrb_value idx) { mrb_int i; if (mrb_string_p(idx) || mrb_symbol_p(idx)) { return mrb_struct_aref_id(mrb, s, mrb_to_id(mrb, idx)); } i = mrb_fixnum(idx); if (i < 0) i = RSTRUCT_LEN(s) + i; if (i < 0) mrb_raisef(mrb, E_INDEX_ERROR, "offset %" PRIdMRB_INT " too small for struct(size:%" PRIdMRB_INT ")", i, RSTRUCT_LEN(s)); if (RSTRUCT_LEN(s) <= i) mrb_raisef(mrb, E_INDEX_ERROR, "offset %" PRIdMRB_INT " too large for struct(size:%" PRIdMRB_INT ")", i, RSTRUCT_LEN(s)); return RSTRUCT_PTR(s)[i]; }
/* * call-seq: * obj.instance_variable_defined?(symbol) -> true or false * * Returns <code>true</code> if the given instance variable is * defined in <i>obj</i>. * * class Fred * def initialize(p1, p2) * @a, @b = p1, p2 * end * end * fred = Fred.new('cat', 99) * fred.instance_variable_defined?(:@a) #=> true * fred.instance_variable_defined?("@b") #=> true * fred.instance_variable_defined?("@c") #=> false */ mrb_value mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self) { mrb_value arg; khiter_t k; kh_iv_t *h = RCLASS_IV_TBL(self); mrb_get_args(mrb, "o", &arg); mrb_sym mid = mrb_to_id(mrb, arg); //if (!mrb_is_instance_id(id)) { // mrb_name_error(id, "`%s' is not allowed as an instance variable name", mrb_sym2name(mrb, id)); //} //return mrb_ivar_defined(self, id); k = kh_get(iv, h, mid); if (k != kh_end(h)) { return mrb_true_value(); } else { return mrb_false_value(); } }
/* * call-seq: * obj.remove_instance_variable(symbol) -> obj * * Removes the named instance variable from <i>obj</i>, returning that * variable's value. * * class Dummy * attr_reader :var * def initialize * @var = 99 * end * def remove * remove_instance_variable(:@var) * end * end * d = Dummy.new * d.var #=> 99 * d.remove #=> 99 * d.var #=> nil */ mrb_value mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self) { mrb_sym sym; mrb_value name; khash_t(iv) *h; khiter_t k; mrb_value val; mrb_value Qundef = mrb_undef_value(); mrb_get_args(mrb, "o", &name); sym = mrb_to_id(mrb, name); //if (OBJ_FROZEN(obj)) mrb_error_frozen("object"); //if (!mrb_is_instance_id(id)) { // mrb_name_error(mrb, id, "`%s' is not allowed as an instance variable name", mrb_sym2name(mrb, id)); //} switch (mrb_type(self)) { case MRB_TT_OBJECT: case MRB_TT_CLASS: case MRB_TT_MODULE: if (!mrb_obj_ptr(self)->iv) break; h = mrb_obj_ptr(self)->iv; if (!h) break; k = kh_get(iv, h, sym); if (k != kh_end(h)) { val = kh_value(h, k); if (!mrb_obj_equal(mrb, val, Qundef)) { kh_value(h, k) = Qundef; return val; } } break; default: break; } mrb_name_error(mrb, sym, "instance variable %s not defined", mrb_sym2name(mrb, sym)); return mrb_nil_value(); /* not reached */ }