Пример #1
0
        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;
        }