Object* Module::cvar_set(STATE, Symbol* name, Object* value) { if(!name->is_cvar_p(state)->true_p()) return Primitives::failure(); check_frozen(state); Module* mod = this; Module* mod_to_query; while(!mod->nil_p()) { mod_to_query = get_module_to_query(mod); if(mod_to_query->table_ivar_defined(state, name)->true_p()) { mod_to_query->set_table_ivar(state, name, value); return value; } mod = mod->superclass(); } mod = this; mod_to_query = get_module_to_query(mod); mod_to_query->set_ivar(state, name, value); return value; }
Object* Module::cvar_set(STATE, Symbol* name, Object* value) { if(!name->is_cvar_p(state)->true_p()) return Primitives::failure(); if(CBOOL(frozen_p(state))) { Exception::type_error(state, "unable to change frozen object"); } Module* mod = this; Module* mod_to_query; while(!mod->nil_p()) { mod_to_query = get_module_to_query(mod); if(mod_to_query->table_ivar_defined(state, name)->true_p()) { mod_to_query->set_table_ivar(state, name, value); return value; } mod = mod->superclass(); } mod = this; mod_to_query = get_module_to_query(mod); mod_to_query->set_ivar(state, name, value); return value; }
Array* Module::class_variables(STATE) { Array* ary = Array::create(state, 2); Module* mod = this; Module* mod_to_query; class cvar_match : public ObjectMatcher { public: virtual bool match_p(STATE, Object* obj) { if(Symbol* sym = try_as<Symbol>(obj)) { return sym->is_cvar_p(state)->true_p(); } return false; }; } match; while(!mod->nil_p()) { mod_to_query = get_module_to_query(mod); Object* ivars = mod_to_query->ivars(); if(CompactLookupTable* tbl = try_as<CompactLookupTable>(ivars)) { ary->concat(state, tbl->filtered_keys(state, match)); } else if(LookupTable* tbl = try_as<LookupTable>(ivars)) { ary->concat(state, tbl->filtered_keys(state, match)); } mod = mod->superclass(); } return ary; }
Object* Module::cvar_defined(STATE, Symbol* name) { if(!name->is_cvar_p(state)->true_p()) return Primitives::failure(); Module* mod = this; while(!mod->nil_p()) { Module* mod_to_query = get_module_to_query(mod); if(mod_to_query->table_ivar_defined(state, name)->true_p()) return cTrue; mod = mod->superclass(); } return cFalse; }
Object* Module::cvar_remove(STATE, Symbol* name) { if(!name->is_cvar_p(state)->true_p()) return Primitives::failure(); Module* mod = this; Module* mod_to_query; mod_to_query = get_module_to_query(mod); bool removed = false; Object* value = mod_to_query->del_table_ivar(state, name, &removed); if(removed) return value; std::ostringstream ss; mod = this; if(SingletonClass* sc = try_as<SingletonClass>(mod)) { mod = as<Module>(sc->attached_instance()); } if (this->cvar_defined(state, name) == cTrue) { ss << "cannot remove "; ss << name->debug_str(state); ss << " for "; } else { ss << "uninitialized class variable "; ss << name->debug_str(state); ss << " in module "; } if(mod->name()->nil_p()) { if(kind_of<Class>(mod)) { ss << "#<Class>"; } else { ss << "#<Module>"; } } else { ss << mod->name()->debug_str(state); } RubyException::raise( Exception::make_exception(state, as<Class>(G(object)->get_const(state, "NameError")), ss.str().c_str())); return NULL; }
Object* Module::cvar_get(STATE, Symbol* name) { if(!name->is_cvar_p(state)->true_p()) return Primitives::failure(); Module* mod = this; Module* mod_to_query; while(!mod->nil_p()) { mod_to_query = get_module_to_query(mod); if(mod_to_query->table_ivar_defined(state, name)->true_p()) { return mod_to_query->get_table_ivar(state, name); } mod = mod->superclass(); } mod = this; if(SingletonClass* sc = try_as<SingletonClass>(mod)) { mod = as<Module>(sc->attached_instance()); } std::ostringstream ss; ss << "uninitialized class variable "; ss << name->debug_str(state); ss << " in module "; if(mod->module_name()->nil_p()) { if(kind_of<Class>(mod)) { ss << "#<Class>"; } else { ss << "#<Module>"; } } else { ss << mod->debug_str(state); } RubyException::raise( Exception::make_exception(state, as<Class>(G(object)->get_const(state, "NameError")), ss.str().c_str())); return NULL; }