From: nobu.nokada@... Date: 2002-08-08T12:02:10+09:00 Subject: Re: struct needs to be a constant? Hi, At Thu, 8 Aug 2002 06:01:35 +0900, GOTO Kentaro wrote: > > test.rb:3:in `require': identifier Proto::ProtoStruct needs to be constant (NameError) from > > test.rb:3 > > > void Init_proto() > > { > > VALUE np_mNet; > > np_mNet = rb_define_module("Net"); > > cNetProto = rb_define_class_under(np_mNet,"Proto",rb_cObject); > > > > sProto = rb_struct_define("Proto::ProtoStruct","name","aliases","number",0); > > rb_global_variable(&sProto); > > try replacing the last two lines by > > sProto = rb_struct_define("ProtoStruct","name","aliases","number",0); > rb_define_const(cNetProto, "ProtoStruct", sProto); This pollute Struct namespace, to avoid it: * rb_struct_define() with NULL for first argument, * rb_define_const() like above, and * name the Struct with rb_set_class_path(). BTW, how about this, singleton methods "[]" which accepts protocol name/number and "each" alias of "getprotent", and extening Net::Proto with Enumerable. require "net/proto" p Net::Proto["tcp"], Net::Proto[6] Net::Proto.each {|proto| p proto} p Net::Proto.to_a #include "ruby.h" #include #include #define BUF_SIZE 8192 static VALUE np_getprotobyname(VALUE obj, VALUE proto_name) { struct protoent p, *r; char buffer[BUF_SIZE]; getprotobyname_r(StringValuePtr(proto_name), &p, buffer, BUF_SIZE, &r); return INT2NUM(p.p_proto); } static VALUE np_getprotobynumber(VALUE obj, VALUE proto_number) { struct protoent p, *r; char buffer[BUF_SIZE]; getprotobynumber_r(NUM2INT(proto_number), &p, buffer, BUF_SIZE, &r); return rb_str_new2(p.p_name); } static VALUE np_aref(VALUE obj, VALUE proto) { if (TYPE(proto) == T_STRING) { return np_getprotobyname(obj, proto); } else { return np_getprotobynumber(obj, proto); } } static VALUE np_getprotoent(VALUE self) { struct protoent p, *r; char buffer[BUF_SIZE]; while (!getprotoent_r(&p, buffer, BUF_SIZE, &r)) { VALUE alias_array = rb_ary_new(); for (; *p.p_aliases != NULL; p.p_aliases++) { rb_ary_push(alias_array, rb_str_new2(*p.p_aliases)); } rb_yield(rb_struct_new(self, rb_str_new2(p.p_name), alias_array, INT2NUM(p.p_proto))); } } void Init_proto() { VALUE np_mNet, cNetProto; np_mNet = rb_define_module("Net"); cNetProto = rb_struct_define(NULL, "name", "aliases", "proto", 0); rb_extend_object(cNetProto, rb_mEnumerable); rb_define_const(np_mNet, "Proto", cNetProto); rb_set_class_path(cNetProto, np_mNet, "Proto"); rb_define_singleton_method(cNetProto, "getprotobyname", np_getprotobyname, 1); rb_define_singleton_method(cNetProto, "getprotobynumber", np_getprotobynumber, 1); rb_define_singleton_method(cNetProto, "getprotoent", np_getprotoent, 0); rb_define_singleton_method(cNetProto, "[]", np_aref, 1); rb_define_singleton_method(cNetProto, "each", np_getprotoent, 0); } -- Nobu Nakada