00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "ruby.h"
00014 #include "env.h"
00015
00016 VALUE rb_cStruct;
00017
00018 static VALUE struct_alloc (VALUE);
00019
00020 VALUE
00021 rb_struct_iv_get(c, name)
00022 VALUE c;
00023 char *name;
00024 {
00025 ID id;
00026
00027 id = rb_intern(name);
00028 for (;;) {
00029 if (rb_ivar_defined(c, id))
00030 return rb_ivar_get(c, id);
00031 c = RCLASS(c)->super;
00032 if (c == 0 || c == rb_cStruct)
00033 return Qnil;
00034 }
00035 }
00036
00037 VALUE
00038 rb_struct_s_members(klass)
00039 VALUE klass;
00040 {
00041 VALUE members = rb_struct_iv_get(klass, "__members__");
00042
00043 if (NIL_P(members)) {
00044 rb_bug("non-initialized struct");
00045 }
00046 return members;
00047 }
00048
00049 VALUE
00050 rb_struct_members(s)
00051 VALUE s;
00052 {
00053 VALUE members = rb_struct_s_members(rb_obj_class(s));
00054
00055 if (RSTRUCT(s)->len != RARRAY(members)->len) {
00056 rb_raise(rb_eTypeError, "struct size differs (%d required %d given)",
00057 RARRAY(members)->len, RSTRUCT(s)->len);
00058 }
00059 return members;
00060 }
00061
00062 static VALUE
00063 rb_struct_s_members_m(klass)
00064 VALUE klass;
00065 {
00066 VALUE members, ary;
00067 VALUE *p, *pend;
00068
00069 members = rb_struct_s_members(klass);
00070 ary = rb_ary_new2(RARRAY(members)->len);
00071 p = RARRAY(members)->ptr; pend = p + RARRAY(members)->len;
00072 while (p < pend) {
00073 rb_ary_push(ary, rb_str_new2(rb_id2name(SYM2ID(*p))));
00074 p++;
00075 }
00076
00077 return ary;
00078 }
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 static VALUE
00093 rb_struct_members_m(obj)
00094 VALUE obj;
00095 {
00096 return rb_struct_s_members_m(rb_obj_class(obj));
00097 }
00098
00099 VALUE
00100 rb_struct_getmember(obj, id)
00101 VALUE obj;
00102 ID id;
00103 {
00104 VALUE members, slot;
00105 long i;
00106
00107 members = rb_struct_members(obj);
00108 slot = ID2SYM(id);
00109 for (i=0; i<RARRAY(members)->len; i++) {
00110 if (RARRAY(members)->ptr[i] == slot) {
00111 return RSTRUCT(obj)->ptr[i];
00112 }
00113 }
00114 rb_name_error(id, "%s is not struct member", rb_id2name(id));
00115 return Qnil;
00116 }
00117
00118 static VALUE
00119 rb_struct_ref(obj)
00120 VALUE obj;
00121 {
00122 return rb_struct_getmember(obj, ruby_frame->orig_func);
00123 }
00124
00125 static VALUE rb_struct_ref0(obj) VALUE obj; {return RSTRUCT(obj)->ptr[0];}
00126 static VALUE rb_struct_ref1(obj) VALUE obj; {return RSTRUCT(obj)->ptr[1];}
00127 static VALUE rb_struct_ref2(obj) VALUE obj; {return RSTRUCT(obj)->ptr[2];}
00128 static VALUE rb_struct_ref3(obj) VALUE obj; {return RSTRUCT(obj)->ptr[3];}
00129 static VALUE rb_struct_ref4(obj) VALUE obj; {return RSTRUCT(obj)->ptr[4];}
00130 static VALUE rb_struct_ref5(obj) VALUE obj; {return RSTRUCT(obj)->ptr[5];}
00131 static VALUE rb_struct_ref6(obj) VALUE obj; {return RSTRUCT(obj)->ptr[6];}
00132 static VALUE rb_struct_ref7(obj) VALUE obj; {return RSTRUCT(obj)->ptr[7];}
00133 static VALUE rb_struct_ref8(obj) VALUE obj; {return RSTRUCT(obj)->ptr[8];}
00134 static VALUE rb_struct_ref9(obj) VALUE obj; {return RSTRUCT(obj)->ptr[9];}
00135
00136 static VALUE (*ref_func[10])() = {
00137 rb_struct_ref0,
00138 rb_struct_ref1,
00139 rb_struct_ref2,
00140 rb_struct_ref3,
00141 rb_struct_ref4,
00142 rb_struct_ref5,
00143 rb_struct_ref6,
00144 rb_struct_ref7,
00145 rb_struct_ref8,
00146 rb_struct_ref9,
00147 };
00148
00149 static void
00150 rb_struct_modify(s)
00151 VALUE s;
00152 {
00153 if (OBJ_FROZEN(s)) rb_error_frozen("Struct");
00154 if (!OBJ_TAINTED(s) && rb_safe_level() >= 4)
00155 rb_raise(rb_eSecurityError, "Insecure: can't modify Struct");
00156 }
00157
00158 static VALUE
00159 rb_struct_set(obj, val)
00160 VALUE obj, val;
00161 {
00162 VALUE members, slot;
00163 ID id;
00164 long i;
00165
00166 members = rb_struct_members(obj);
00167 rb_struct_modify(obj);
00168 id = ruby_frame->orig_func;
00169 for (i=0; i<RARRAY(members)->len; i++) {
00170 slot = RARRAY(members)->ptr[i];
00171 if (rb_id_attrset(SYM2ID(slot)) == id) {
00172 return RSTRUCT(obj)->ptr[i] = val;
00173 }
00174 }
00175 rb_name_error(ruby_frame->last_func, "`%s' is not a struct member",
00176 rb_id2name(id));
00177 return Qnil;
00178 }
00179
00180 static VALUE
00181 make_struct(name, members, klass)
00182 VALUE name, members, klass;
00183 {
00184 VALUE nstr;
00185 ID id;
00186 long i;
00187
00188 OBJ_FREEZE(members);
00189 if (NIL_P(name)) {
00190 nstr = rb_class_new(klass);
00191 rb_make_metaclass(nstr, RBASIC(klass)->klass);
00192 rb_class_inherited(klass, nstr);
00193 }
00194 else {
00195 char *cname = StringValuePtr(name);
00196 id = rb_intern(cname);
00197 if (!rb_is_const_id(id)) {
00198 rb_name_error(id, "identifier %s needs to be constant", cname);
00199 }
00200 if (rb_const_defined_at(klass, id)) {
00201 rb_warn("redefining constant Struct::%s", cname);
00202 rb_mod_remove_const(klass, ID2SYM(id));
00203 }
00204 nstr = rb_define_class_under(klass, rb_id2name(id), klass);
00205 }
00206 rb_iv_set(nstr, "__size__", LONG2NUM(RARRAY(members)->len));
00207 rb_iv_set(nstr, "__members__", members);
00208
00209 rb_define_alloc_func(nstr, struct_alloc);
00210 rb_define_singleton_method(nstr, "new", rb_class_new_instance, -1);
00211 rb_define_singleton_method(nstr, "[]", rb_class_new_instance, -1);
00212 rb_define_singleton_method(nstr, "members", rb_struct_s_members_m, 0);
00213 for (i=0; i< RARRAY(members)->len; i++) {
00214 ID id = SYM2ID(RARRAY(members)->ptr[i]);
00215 if (rb_is_local_id(id) || rb_is_const_id(id)) {
00216 if (i<10) {
00217 rb_define_method_id(nstr, id, ref_func[i], 0);
00218 }
00219 else {
00220 rb_define_method_id(nstr, id, rb_struct_ref, 0);
00221 }
00222 rb_define_method_id(nstr, rb_id_attrset(id), rb_struct_set, 1);
00223 }
00224 }
00225
00226 return nstr;
00227 }
00228
00229 #ifdef HAVE_STDARG_PROTOTYPES
00230 #include <stdarg.h>
00231 #define va_init_list(a,b) va_start(a,b)
00232 #else
00233 #include <varargs.h>
00234 #define va_init_list(a,b) va_start(a)
00235 #endif
00236
00237 VALUE
00238 #ifdef HAVE_STDARG_PROTOTYPES
00239 rb_struct_define(const char *name, ...)
00240 #else
00241 rb_struct_define(name, va_alist)
00242 const char *name;
00243 va_dcl
00244 #endif
00245 {
00246 va_list ar;
00247 VALUE nm, ary;
00248 char *mem;
00249
00250 if (!name) nm = Qnil;
00251 else nm = rb_str_new2(name);
00252 ary = rb_ary_new();
00253
00254 va_init_list(ar, name);
00255 while (mem = va_arg(ar, char*)) {
00256 ID slot = rb_intern(mem);
00257 rb_ary_push(ary, ID2SYM(slot));
00258 }
00259 va_end(ar);
00260
00261 return make_struct(nm, ary, rb_cStruct);
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 static VALUE
00299 rb_struct_s_def(argc, argv, klass)
00300 int argc;
00301 VALUE *argv;
00302 VALUE klass;
00303 {
00304 VALUE name, rest;
00305 long i;
00306 VALUE st;
00307 ID id;
00308
00309 rb_scan_args(argc, argv, "1*", &name, &rest);
00310 for (i=0; i<RARRAY(rest)->len; i++) {
00311 id = rb_to_id(RARRAY(rest)->ptr[i]);
00312 RARRAY(rest)->ptr[i] = ID2SYM(id);
00313 }
00314 if (!NIL_P(name)) {
00315 VALUE tmp = rb_check_string_type(name);
00316
00317 if (NIL_P(tmp)) {
00318 id = rb_to_id(name);
00319 rb_ary_unshift(rest, ID2SYM(id));
00320 name = Qnil;
00321 }
00322 }
00323 st = make_struct(name, rest, klass);
00324 if (rb_block_given_p()) {
00325 rb_mod_module_eval(0, 0, st);
00326 }
00327
00328 return st;
00329 }
00330
00331
00332
00333
00334 static VALUE
00335 rb_struct_initialize(self, values)
00336 VALUE self, values;
00337 {
00338 VALUE klass = rb_obj_class(self);
00339 VALUE size;
00340 long n;
00341
00342 rb_struct_modify(self);
00343 size = rb_struct_iv_get(klass, "__size__");
00344 n = FIX2LONG(size);
00345 if (n < RARRAY(values)->len) {
00346 rb_raise(rb_eArgError, "struct size differs");
00347 }
00348 MEMCPY(RSTRUCT(self)->ptr, RARRAY(values)->ptr, VALUE, RARRAY(values)->len);
00349 if (n > RARRAY(values)->len) {
00350 rb_mem_clear(RSTRUCT(self)->ptr+RARRAY(values)->len,
00351 n-RARRAY(values)->len);
00352 }
00353 return Qnil;
00354 }
00355
00356 static VALUE
00357 struct_alloc(klass)
00358 VALUE klass;
00359 {
00360 VALUE size;
00361 long n;
00362 NEWOBJ(st, struct RStruct);
00363 OBJSETUP(st, klass, T_STRUCT);
00364
00365 size = rb_struct_iv_get(klass, "__size__");
00366 n = FIX2LONG(size);
00367
00368 st->ptr = ALLOC_N(VALUE, n);
00369 rb_mem_clear(st->ptr, n);
00370 st->len = n;
00371
00372 return (VALUE)st;
00373 }
00374
00375 VALUE
00376 rb_struct_alloc(klass, values)
00377 VALUE klass, values;
00378 {
00379 return rb_class_new_instance(RARRAY(values)->len, RARRAY(values)->ptr, klass);
00380 }
00381
00382 VALUE
00383 #ifdef HAVE_STDARG_PROTOTYPES
00384 rb_struct_new(VALUE klass, ...)
00385 #else
00386 rb_struct_new(klass, va_alist)
00387 VALUE klass;
00388 va_dcl
00389 #endif
00390 {
00391 VALUE sz, *mem;
00392 long size, i;
00393 va_list args;
00394
00395 sz = rb_struct_iv_get(klass, "__size__");
00396 size = FIX2LONG(sz);
00397 mem = ALLOCA_N(VALUE, size);
00398 va_init_list(args, klass);
00399 for (i=0; i<size; i++) {
00400 mem[i] = va_arg(args, VALUE);
00401 }
00402 va_end(args);
00403
00404 return rb_class_new_instance(size, mem, klass);
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 static VALUE
00426 rb_struct_each(s)
00427 VALUE s;
00428 {
00429 long i;
00430
00431 for (i=0; i<RSTRUCT(s)->len; i++) {
00432 rb_yield(RSTRUCT(s)->ptr[i]);
00433 }
00434 return s;
00435 }
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 static VALUE
00456 rb_struct_each_pair(s)
00457 VALUE s;
00458 {
00459 VALUE members;
00460 long i;
00461
00462 members = rb_struct_members(s);
00463 for (i=0; i<RSTRUCT(s)->len; i++) {
00464 rb_yield_values(2, rb_ary_entry(members, i), RSTRUCT(s)->ptr[i]);
00465 }
00466 return s;
00467 }
00468
00469 static VALUE
00470 inspect_struct(s)
00471 VALUE s;
00472 {
00473 char *cname = rb_class2name(rb_obj_class(s));
00474 VALUE str, members;
00475 long i;
00476
00477 members = rb_struct_members(s);
00478 str = rb_str_buf_new2("#<struct ");
00479 rb_str_cat2(str, cname);
00480 rb_str_cat2(str, " ");
00481 for (i=0; i<RSTRUCT(s)->len; i++) {
00482 VALUE slot;
00483 ID id;
00484 char *p;
00485
00486 if (i > 0) {
00487 rb_str_cat2(str, ", ");
00488 }
00489 slot = RARRAY(members)->ptr[i];
00490 id = SYM2ID(slot);
00491 if (rb_is_local_id(id) || rb_is_const_id(id)) {
00492 p = rb_id2name(id);
00493 rb_str_cat2(str, p);
00494 }
00495 else {
00496 rb_str_append(str, rb_inspect(slot));
00497 }
00498 rb_str_cat2(str, "=");
00499 rb_str_append(str, rb_inspect(RSTRUCT(s)->ptr[i]));
00500 }
00501 rb_str_cat2(str, ">");
00502 OBJ_INFECT(str, s);
00503
00504 return str;
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 static VALUE
00516 rb_struct_inspect(s)
00517 VALUE s;
00518 {
00519 if (rb_inspecting_p(s)) {
00520 char *cname = rb_class2name(rb_obj_class(s));
00521 size_t len = strlen(cname) + 14;
00522 VALUE str = rb_str_new(0, len);
00523
00524 snprintf(RSTRING(str)->ptr, len+1, "#<struct %s:...>", cname);
00525 RSTRING(str)->len = strlen(RSTRING(str)->ptr);
00526 return str;
00527 }
00528 return rb_protect_inspect(inspect_struct, s, 0);
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543 static VALUE
00544 rb_struct_to_a(s)
00545 VALUE s;
00546 {
00547 return rb_ary_new4(RSTRUCT(s)->len, RSTRUCT(s)->ptr);
00548 }
00549
00550
00551 static VALUE
00552 rb_struct_init_copy(copy, s)
00553 VALUE copy, s;
00554 {
00555 if (copy == s) return copy;
00556 rb_check_frozen(copy);
00557 if (!rb_obj_is_instance_of(s, rb_obj_class(copy))) {
00558 rb_raise(rb_eTypeError, "wrong argument class");
00559 }
00560 RSTRUCT(copy)->ptr = ALLOC_N(VALUE, RSTRUCT(s)->len);
00561 RSTRUCT(copy)->len = RSTRUCT(s)->len;
00562 MEMCPY(RSTRUCT(copy)->ptr, RSTRUCT(s)->ptr, VALUE, RSTRUCT(copy)->len);
00563
00564 return copy;
00565 }
00566
00567 static VALUE
00568 rb_struct_aref_id(s, id)
00569 VALUE s;
00570 ID id;
00571 {
00572 VALUE members;
00573 long i, len;
00574
00575 members = rb_struct_members(s);
00576 len = RARRAY(members)->len;
00577 for (i=0; i<len; i++) {
00578 if (SYM2ID(RARRAY(members)->ptr[i]) == id) {
00579 return RSTRUCT(s)->ptr[i];
00580 }
00581 }
00582 rb_name_error(id, "no member '%s' in struct", rb_id2name(id));
00583 return Qnil;
00584 }
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605 VALUE
00606 rb_struct_aref(s, idx)
00607 VALUE s, idx;
00608 {
00609 long i;
00610
00611 if (TYPE(idx) == T_STRING || TYPE(idx) == T_SYMBOL) {
00612 return rb_struct_aref_id(s, rb_to_id(idx));
00613 }
00614
00615 i = NUM2LONG(idx);
00616 if (i < 0) i = RSTRUCT(s)->len + i;
00617 if (i < 0)
00618 rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
00619 i, RSTRUCT(s)->len);
00620 if (RSTRUCT(s)->len <= i)
00621 rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
00622 i, RSTRUCT(s)->len);
00623 return RSTRUCT(s)->ptr[i];
00624 }
00625
00626 static VALUE
00627 rb_struct_aset_id(s, id, val)
00628 VALUE s, val;
00629 ID id;
00630 {
00631 VALUE members;
00632 long i, len;
00633
00634 members = rb_struct_members(s);
00635 rb_struct_modify(s);
00636 len = RARRAY(members)->len;
00637 if (RSTRUCT(s)->len != RARRAY(members)->len) {
00638 rb_raise(rb_eTypeError, "struct size differs (%d required %d given)",
00639 RARRAY(members)->len, RSTRUCT(s)->len);
00640 }
00641 for (i=0; i<len; i++) {
00642 if (SYM2ID(RARRAY(members)->ptr[i]) == id) {
00643 RSTRUCT(s)->ptr[i] = val;
00644 return val;
00645 }
00646 }
00647 rb_name_error(id, "no member '%s' in struct", rb_id2name(id));
00648 }
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671 VALUE
00672 rb_struct_aset(s, idx, val)
00673 VALUE s, idx, val;
00674 {
00675 long i;
00676
00677 if (TYPE(idx) == T_STRING || TYPE(idx) == T_SYMBOL) {
00678 return rb_struct_aset_id(s, rb_to_id(idx), val);
00679 }
00680
00681 i = NUM2LONG(idx);
00682 if (i < 0) i = RSTRUCT(s)->len + i;
00683 if (i < 0) {
00684 rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
00685 i, RSTRUCT(s)->len);
00686 }
00687 if (RSTRUCT(s)->len <= i) {
00688 rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
00689 i, RSTRUCT(s)->len);
00690 }
00691 rb_struct_modify(s);
00692 return RSTRUCT(s)->ptr[i] = val;
00693 }
00694
00695 static VALUE struct_entry (VALUE, long);
00696 static VALUE
00697 struct_entry(s, n)
00698 VALUE s;
00699 long n;
00700 {
00701 return rb_struct_aref(s, LONG2NUM(n));
00702 }
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720 static VALUE
00721 rb_struct_values_at(argc, argv, s)
00722 int argc;
00723 VALUE *argv;
00724 VALUE s;
00725 {
00726 return rb_values_at(s, RSTRUCT(s)->len, argc, argv, struct_entry);
00727 }
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749 static VALUE
00750 rb_struct_select(argc, argv, s)
00751 int argc;
00752 VALUE *argv;
00753 VALUE s;
00754 {
00755 VALUE result;
00756 long i;
00757
00758 if (argc > 0) {
00759 rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
00760 }
00761 result = rb_ary_new();
00762 for (i = 0; i < RSTRUCT(s)->len; i++) {
00763 if (RTEST(rb_yield(RSTRUCT(s)->ptr[i]))) {
00764 rb_ary_push(result, RSTRUCT(s)->ptr[i]);
00765 }
00766 }
00767
00768 return result;
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788 static VALUE
00789 rb_struct_equal(s, s2)
00790 VALUE s, s2;
00791 {
00792 long i;
00793
00794 if (s == s2) return Qtrue;
00795 if (TYPE(s2) != T_STRUCT) return Qfalse;
00796 if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
00797 if (RSTRUCT(s)->len != RSTRUCT(s2)->len) {
00798 rb_bug("inconsistent struct");
00799 }
00800
00801 for (i=0; i<RSTRUCT(s)->len; i++) {
00802 if (!rb_equal(RSTRUCT(s)->ptr[i], RSTRUCT(s2)->ptr[i])) return Qfalse;
00803 }
00804 return Qtrue;
00805 }
00806
00807
00808
00809
00810
00811
00812
00813
00814 static VALUE
00815 rb_struct_hash(s)
00816 VALUE s;
00817 {
00818 long i, h;
00819 VALUE n;
00820
00821 h = rb_hash(rb_obj_class(s));
00822 for (i = 0; i < RSTRUCT(s)->len; i++) {
00823 h = (h << 1) | (h<0 ? 1 : 0);
00824 n = rb_hash(RSTRUCT(s)->ptr[i]);
00825 h ^= NUM2LONG(n);
00826 }
00827 return LONG2FIX(h);
00828 }
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 static VALUE
00839 rb_struct_eql(s, s2)
00840 VALUE s, s2;
00841 {
00842 long i;
00843
00844 if (s == s2) return Qtrue;
00845 if (TYPE(s2) != T_STRUCT) return Qfalse;
00846 if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
00847 if (RSTRUCT(s)->len != RSTRUCT(s2)->len) {
00848 rb_bug("inconsistent struct");
00849 }
00850
00851 for (i=0; i<RSTRUCT(s)->len; i++) {
00852 if (!rb_eql(RSTRUCT(s)->ptr[i], RSTRUCT(s2)->ptr[i])) return Qfalse;
00853 }
00854 return Qtrue;
00855 }
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 static VALUE
00870 rb_struct_size(s)
00871 VALUE s;
00872 {
00873 return LONG2FIX(RSTRUCT(s)->len);
00874 }
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891 void
00892 Init_Struct()
00893 {
00894 rb_cStruct = rb_define_class("Struct", rb_cObject);
00895 rb_include_module(rb_cStruct, rb_mEnumerable);
00896
00897 rb_undef_alloc_func(rb_cStruct);
00898 rb_define_singleton_method(rb_cStruct, "new", rb_struct_s_def, -1);
00899
00900 rb_define_method(rb_cStruct, "initialize", rb_struct_initialize, -2);
00901 rb_define_method(rb_cStruct, "initialize_copy", rb_struct_init_copy, 1);
00902
00903 rb_define_method(rb_cStruct, "==", rb_struct_equal, 1);
00904 rb_define_method(rb_cStruct, "eql?", rb_struct_eql, 1);
00905 rb_define_method(rb_cStruct, "hash", rb_struct_hash, 0);
00906
00907 rb_define_method(rb_cStruct, "to_s", rb_struct_inspect, 0);
00908 rb_define_method(rb_cStruct, "inspect", rb_struct_inspect, 0);
00909 rb_define_method(rb_cStruct, "to_a", rb_struct_to_a, 0);
00910 rb_define_method(rb_cStruct, "values", rb_struct_to_a, 0);
00911 rb_define_method(rb_cStruct, "size", rb_struct_size, 0);
00912 rb_define_method(rb_cStruct, "length", rb_struct_size, 0);
00913
00914 rb_define_method(rb_cStruct, "each", rb_struct_each, 0);
00915 rb_define_method(rb_cStruct, "each_pair", rb_struct_each_pair, 0);
00916 rb_define_method(rb_cStruct, "[]", rb_struct_aref, 1);
00917 rb_define_method(rb_cStruct, "[]=", rb_struct_aset, 2);
00918 rb_define_method(rb_cStruct, "select", rb_struct_select, -1);
00919 rb_define_method(rb_cStruct, "values_at", rb_struct_values_at, -1);
00920
00921 rb_define_method(rb_cStruct, "members", rb_struct_members_m, 0);
00922 }
00923