internal static Class make_struct(string name, Array members, Class klass, Frame caller) { // Compiler Bug???: Found bug here the following code crashes this method: // Customer = Struct.new( :name, :address, :zip ) // FIXME: OBJ_FREEZE(members); Class nstr = null; if (name == null) { nstr = new Class(null, klass, Class.Type.Class); Class.rb_make_metaclass(nstr, klass.my_class); nstr.class_inherited(klass, caller); } else { if (!Symbol.is_const_id(name)) { throw new NameError("identifier " + name + " needs to be constant").raise(caller); } if (klass.const_defined(name, false)) { // rb_warn klass.remove_const(name); } nstr = Class.rb_define_class_under(klass, name, klass, caller); } nstr.instance_variable_set("__size__", members.Count); nstr.instance_variable_set("__members__", members); Class.rb_define_alloc_func(nstr, Methods.struct_alloc.singleton); Class.rb_define_singleton_method(nstr, "new", Methods.rb_class_new_instance.singleton, -1, caller); Class.rb_define_singleton_method(nstr, "[]", Methods.rb_class_new_instance.singleton, -1, caller); Class.rb_define_singleton_method(nstr, "members", Methods.rb_struct_s_members.singleton, 0, caller); foreach (object m in members) { string id = Symbol.rb_to_id(caller, m); if (Symbol.is_local_id(id) || Symbol.is_const_id(id)) { Class.rb_define_method(nstr, id, new AttrReaderMethodBody(id), 0, caller); Class.rb_define_method(nstr, id + "=", new AttrWriterMethodBody(id), 1, caller); } } return nstr; }
internal static object const_get(Class current, string id, Frame caller) { if (current.const_defined(id, false)) return current.const_get(id, caller); foreach (Class klass in caller.nesting()) if (klass.const_defined(id, false)) return klass.const_get(id, caller); return current.const_get(id, caller); }
internal static bool const_defined(Class current, string id, Frame caller) { if (current.const_defined(id, false)) return true; foreach (Class klass in caller.nesting()) if (klass.const_defined(id, false)) return true; return current.const_defined(id, true); }