Ruby  2.5.0dev(2017-10-22revision60238)
struct.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  struct.c -
4 
5  $Author$
6  created at: Tue Mar 22 18:44:30 JST 1995
7 
8  Copyright (C) 1993-2007 Yukihiro Matsumoto
9 
10 **********************************************************************/
11 
12 #include "internal.h"
13 #include "vm_core.h"
14 #include "id.h"
15 
16 /* only for struct[:field] access */
17 enum {
20 };
21 
24 
26 static ID id_members, id_back_members;
27 
28 static VALUE struct_alloc(VALUE);
29 
30 static inline VALUE
31 struct_ivar_get(VALUE c, ID id)
32 {
33  VALUE orig = c;
34  VALUE ivar = rb_attr_get(c, id);
35 
36  if (!NIL_P(ivar))
37  return ivar;
38 
39  for (;;) {
40  c = RCLASS_SUPER(c);
41  if (c == 0 || c == rb_cStruct)
42  return Qnil;
43  ivar = rb_attr_get(c, id);
44  if (!NIL_P(ivar)) {
45  return rb_ivar_set(orig, id, ivar);
46  }
47  }
48 }
49 
50 VALUE
52 {
53  VALUE members = struct_ivar_get(klass, id_members);
54 
55  if (NIL_P(members)) {
56  rb_raise(rb_eTypeError, "uninitialized struct");
57  }
58  if (!RB_TYPE_P(members, T_ARRAY)) {
59  rb_raise(rb_eTypeError, "corrupted struct");
60  }
61  return members;
62 }
63 
64 VALUE
66 {
68 
69  if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) {
70  rb_raise(rb_eTypeError, "struct size differs (%ld required %ld given)",
71  RARRAY_LEN(members), RSTRUCT_LEN(s));
72  }
73  return members;
74 }
75 
76 static long
77 struct_member_pos_ideal(VALUE name, long mask)
78 {
79  /* (id & (mask/2)) * 2 */
80  return (SYM2ID(name) >> (ID_SCOPE_SHIFT - 1)) & mask;
81 }
82 
83 static long
84 struct_member_pos_probe(long prev, long mask)
85 {
86  /* (((prev/2) * AREF_HASH_UNIT + 1) & (mask/2)) * 2 */
87  return (prev * AREF_HASH_UNIT + 2) & mask;
88 }
89 
90 static VALUE
91 struct_set_members(VALUE klass, VALUE /* frozen hidden array */ members)
92 {
93  VALUE back;
94  const long members_length = RARRAY_LEN(members);
95 
96  if (members_length <= AREF_HASH_THRESHOLD) {
97  back = members;
98  }
99  else {
100  long i, j, mask = 64;
101  VALUE name;
102 
103  while (mask < members_length * AREF_HASH_UNIT) mask *= 2;
104 
105  back = rb_ary_tmp_new(mask + 1);
106  rb_ary_store(back, mask, INT2FIX(members_length));
107  mask -= 2; /* mask = (2**k-1)*2 */
108 
109  for (i=0; i < members_length; i++) {
110  name = RARRAY_AREF(members, i);
111 
112  j = struct_member_pos_ideal(name, mask);
113 
114  for (;;) {
115  if (!RTEST(RARRAY_AREF(back, j))) {
116  rb_ary_store(back, j, name);
117  rb_ary_store(back, j + 1, INT2FIX(i));
118  break;
119  }
120  j = struct_member_pos_probe(j, mask);
121  }
122  }
123  OBJ_FREEZE_RAW(back);
124  }
125  rb_ivar_set(klass, id_members, members);
126  rb_ivar_set(klass, id_back_members, back);
127 
128  return members;
129 }
130 
131 static inline int
132 struct_member_pos(VALUE s, VALUE name)
133 {
134  VALUE back = struct_ivar_get(rb_obj_class(s), id_back_members);
135  VALUE const * p;
136  long j, mask;
137 
138  if (UNLIKELY(NIL_P(back))) {
139  rb_raise(rb_eTypeError, "uninitialized struct");
140  }
141  if (UNLIKELY(!RB_TYPE_P(back, T_ARRAY))) {
142  rb_raise(rb_eTypeError, "corrupted struct");
143  }
144 
145  p = RARRAY_CONST_PTR(back);
146  mask = RARRAY_LEN(back);
147 
148  if (mask <= AREF_HASH_THRESHOLD) {
149  if (UNLIKELY(RSTRUCT_LEN(s) != mask)) {
151  "struct size differs (%ld required %ld given)",
152  mask, RSTRUCT_LEN(s));
153  }
154  for (j = 0; j < mask; j++) {
155  if (p[j] == name)
156  return (int)j;
157  }
158  return -1;
159  }
160 
161  if (UNLIKELY(RSTRUCT_LEN(s) != FIX2INT(RARRAY_AREF(back, mask-1)))) {
162  rb_raise(rb_eTypeError, "struct size differs (%d required %ld given)",
163  FIX2INT(RARRAY_AREF(back, mask-1)), RSTRUCT_LEN(s));
164  }
165 
166  mask -= 3;
167  j = struct_member_pos_ideal(name, mask);
168 
169  for (;;) {
170  if (p[j] == name)
171  return FIX2INT(p[j + 1]);
172  if (!RTEST(p[j])) {
173  return -1;
174  }
175  j = struct_member_pos_probe(j, mask);
176  }
177 }
178 
179 static VALUE
180 rb_struct_s_members_m(VALUE klass)
181 {
182  VALUE members = rb_struct_s_members(klass);
183 
184  return rb_ary_dup(members);
185 }
186 
187 /*
188  * call-seq:
189  * struct.members -> array
190  *
191  * Returns the struct members as an array of symbols:
192  *
193  * Customer = Struct.new(:name, :address, :zip)
194  * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
195  * joe.members #=> [:name, :address, :zip]
196  */
197 
198 static VALUE
199 rb_struct_members_m(VALUE obj)
200 {
201  return rb_struct_s_members_m(rb_obj_class(obj));
202 }
203 
204 VALUE
206 {
207  VALUE slot = ID2SYM(id);
208  int i = struct_member_pos(obj, slot);
209  if (i != -1) {
210  return RSTRUCT_GET(obj, i);
211  }
212  rb_name_err_raise("`%1$s' is not a struct member", obj, ID2SYM(id));
213 
214  UNREACHABLE;
215 }
216 
217 static VALUE rb_struct_ref0(VALUE obj) {return RSTRUCT_GET(obj, 0);}
218 static VALUE rb_struct_ref1(VALUE obj) {return RSTRUCT_GET(obj, 1);}
219 static VALUE rb_struct_ref2(VALUE obj) {return RSTRUCT_GET(obj, 2);}
220 static VALUE rb_struct_ref3(VALUE obj) {return RSTRUCT_GET(obj, 3);}
221 static VALUE rb_struct_ref4(VALUE obj) {return RSTRUCT_GET(obj, 4);}
222 static VALUE rb_struct_ref5(VALUE obj) {return RSTRUCT_GET(obj, 5);}
223 static VALUE rb_struct_ref6(VALUE obj) {return RSTRUCT_GET(obj, 6);}
224 static VALUE rb_struct_ref7(VALUE obj) {return RSTRUCT_GET(obj, 7);}
225 static VALUE rb_struct_ref8(VALUE obj) {return RSTRUCT_GET(obj, 8);}
226 static VALUE rb_struct_ref9(VALUE obj) {return RSTRUCT_GET(obj, 9);}
227 
228 #define N_REF_FUNC numberof(ref_func)
229 
230 static VALUE (*const ref_func[])(VALUE) = {
231  rb_struct_ref0,
232  rb_struct_ref1,
233  rb_struct_ref2,
234  rb_struct_ref3,
235  rb_struct_ref4,
236  rb_struct_ref5,
237  rb_struct_ref6,
238  rb_struct_ref7,
239  rb_struct_ref8,
240  rb_struct_ref9,
241 };
242 
243 static void
244 rb_struct_modify(VALUE s)
245 {
246  rb_check_frozen(s);
247  rb_check_trusted(s);
248 }
249 
250 static VALUE
251 anonymous_struct(VALUE klass)
252 {
253  VALUE nstr;
254 
255  nstr = rb_class_new(klass);
256  rb_make_metaclass(nstr, RBASIC(klass)->klass);
257  rb_class_inherited(klass, nstr);
258  return nstr;
259 }
260 
261 static VALUE
262 new_struct(VALUE name, VALUE super)
263 {
264  /* old style: should we warn? */
265  ID id;
266  name = rb_str_to_str(name);
267  if (!rb_is_const_name(name)) {
268  rb_name_err_raise("identifier %1$s needs to be constant",
269  super, name);
270  }
271  id = rb_to_id(name);
272  if (rb_const_defined_at(super, id)) {
273  rb_warn("redefining constant %"PRIsVALUE"::%"PRIsVALUE, super, name);
274  rb_mod_remove_const(super, ID2SYM(id));
275  }
276  return rb_define_class_id_under(super, id, super);
277 }
278 
279 static void
280 define_aref_method(VALUE nstr, VALUE name, VALUE off)
281 {
283  const rb_iseq_t *iseq = rb_method_for_self_aref(name, off, rb_vm_opt_struct_aref);
284 
285  rb_add_method_iseq(nstr, SYM2ID(name), iseq, NULL, METHOD_VISI_PUBLIC);
286 }
287 
288 static void
289 define_aset_method(VALUE nstr, VALUE name, VALUE off)
290 {
292  const rb_iseq_t *iseq = rb_method_for_self_aset(name, off, rb_vm_opt_struct_aset);
293 
294  rb_add_method_iseq(nstr, SYM2ID(name), iseq, NULL, METHOD_VISI_PUBLIC);
295 }
296 
297 static VALUE
298 setup_struct(VALUE nstr, VALUE members)
299 {
300  const VALUE *ptr_members;
301  long i, len;
302 
303  members = struct_set_members(nstr, members);
304 
305  rb_define_alloc_func(nstr, struct_alloc);
308  rb_define_singleton_method(nstr, "members", rb_struct_s_members_m, 0);
309  ptr_members = RARRAY_CONST_PTR(members);
310  len = RARRAY_LEN(members);
311  for (i=0; i< len; i++) {
312  ID id = SYM2ID(ptr_members[i]);
313  VALUE off = LONG2NUM(i);
314 
315  if (i < N_REF_FUNC) {
316  rb_define_method_id(nstr, id, ref_func[i], 0);
317  }
318  else {
319  define_aref_method(nstr, ptr_members[i], off);
320  }
321  define_aset_method(nstr, ID2SYM(rb_id_attrset(id)), off);
322  }
323 
324  return nstr;
325 }
326 
327 VALUE
329 {
330  return struct_alloc(klass);
331 }
332 
333 static VALUE
334 struct_make_members_list(va_list ar)
335 {
336  char *mem;
338  st_table *tbl = RHASH_TBL(list);
339 
340  RBASIC_CLEAR_CLASS(list);
341  while ((mem = va_arg(ar, char*)) != 0) {
343  if (st_insert(tbl, sym, Qtrue)) {
344  rb_raise(rb_eArgError, "duplicate member: %s", mem);
345  }
346  }
347  ary = rb_hash_keys(list);
348  st_clear(tbl);
349  RBASIC_CLEAR_CLASS(ary);
350  OBJ_FREEZE_RAW(ary);
351  return ary;
352 }
353 
354 static VALUE
355 struct_define_without_accessor(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc, VALUE members)
356 {
357  VALUE klass;
358 
359  if (class_name) {
360  if (outer) {
361  klass = rb_define_class_under(outer, class_name, super);
362  }
363  else {
364  klass = rb_define_class(class_name, super);
365  }
366  }
367  else {
368  klass = anonymous_struct(super);
369  }
370 
371  struct_set_members(klass, members);
372 
373  if (alloc) {
374  rb_define_alloc_func(klass, alloc);
375  }
376  else {
377  rb_define_alloc_func(klass, struct_alloc);
378  }
379 
380  return klass;
381 }
382 
383 VALUE
384 rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc, ...)
385 {
386  va_list ar;
387  VALUE members;
388 
389  va_start(ar, alloc);
390  members = struct_make_members_list(ar);
391  va_end(ar);
392 
393  return struct_define_without_accessor(outer, class_name, super, alloc, members);
394 }
395 
396 VALUE
397 rb_struct_define_without_accessor(const char *class_name, VALUE super, rb_alloc_func_t alloc, ...)
398 {
399  va_list ar;
400  VALUE members;
401 
402  va_start(ar, alloc);
403  members = struct_make_members_list(ar);
404  va_end(ar);
405 
406  return struct_define_without_accessor(0, class_name, super, alloc, members);
407 }
408 
409 VALUE
410 rb_struct_define(const char *name, ...)
411 {
412  va_list ar;
413  VALUE st, ary;
414 
415  va_start(ar, name);
416  ary = struct_make_members_list(ar);
417  va_end(ar);
418 
419  if (!name) st = anonymous_struct(rb_cStruct);
420  else st = new_struct(rb_str_new2(name), rb_cStruct);
421  return setup_struct(st, ary);
422 }
423 
424 VALUE
425 rb_struct_define_under(VALUE outer, const char *name, ...)
426 {
427  va_list ar;
428  VALUE ary;
429 
430  va_start(ar, name);
431  ary = struct_make_members_list(ar);
432  va_end(ar);
433 
434  return setup_struct(rb_define_class_under(outer, name, rb_cStruct), ary);
435 }
436 
437 /*
438  * call-seq:
439  * Struct.new([class_name] [, member_name]+) -> StructClass
440  * Struct.new([class_name] [, member_name]+) {|StructClass| block } -> StructClass
441  * StructClass.new(value, ...) -> object
442  * StructClass[value, ...] -> object
443  *
444  * The first two forms are used to create a new Struct subclass +class_name+
445  * that can contain a value for each +member_name+. This subclass can be
446  * used to create instances of the structure like any other Class.
447  *
448  * If the +class_name+ is omitted an anonymous structure class will be
449  * created. Otherwise, the name of this struct will appear as a constant in
450  * class Struct, so it must be unique for all Structs in the system and
451  * must start with a capital letter. Assigning a structure class to a
452  * constant also gives the class the name of the constant.
453  *
454  * # Create a structure with a name under Struct
455  * Struct.new("Customer", :name, :address)
456  * #=> Struct::Customer
457  * Struct::Customer.new("Dave", "123 Main")
458  * #=> #<struct Struct::Customer name="Dave", address="123 Main">
459  *
460  * # Create a structure named by its constant
461  * Customer = Struct.new(:name, :address)
462  * #=> Customer
463  * Customer.new("Dave", "123 Main")
464  * #=> #<struct Customer name="Dave", address="123 Main">
465  *
466  * If a block is given it will be evaluated in the context of
467  * +StructClass+, passing the created class as a parameter:
468  *
469  * Customer = Struct.new(:name, :address) do
470  * def greeting
471  * "Hello #{name}!"
472  * end
473  * end
474  * Customer.new("Dave", "123 Main").greeting #=> "Hello Dave!"
475  *
476  * This is the recommended way to customize a struct. Subclassing an
477  * anonymous struct creates an extra anonymous class that will never be used.
478  *
479  * The last two forms create a new instance of a struct subclass. The number
480  * of +value+ parameters must be less than or equal to the number of
481  * attributes defined for the structure. Unset parameters default to +nil+.
482  * Passing more parameters than number of attributes will raise
483  * an ArgumentError.
484  *
485  * Customer = Struct.new(:name, :address)
486  * Customer.new("Dave", "123 Main")
487  * #=> #<struct Customer name="Dave", address="123 Main">
488  * Customer["Dave"]
489  * #=> #<struct Customer name="Dave", address=nil>
490  */
491 
492 static VALUE
493 rb_struct_s_def(int argc, VALUE *argv, VALUE klass)
494 {
495  VALUE name, rest;
496  long i;
497  VALUE st;
498  st_table *tbl;
499 
501  name = argv[0];
502  if (SYMBOL_P(name)) {
503  name = Qnil;
504  }
505  else {
506  --argc;
507  ++argv;
508  }
509  rest = rb_ident_hash_new();
510  RBASIC_CLEAR_CLASS(rest);
511  tbl = RHASH_TBL(rest);
512  for (i=0; i<argc; i++) {
513  VALUE mem = rb_to_symbol(argv[i]);
514  if (st_insert(tbl, mem, Qtrue)) {
515  rb_raise(rb_eArgError, "duplicate member: %"PRIsVALUE, mem);
516  }
517  }
518  rest = rb_hash_keys(rest);
519  st_clear(tbl);
520  RBASIC_CLEAR_CLASS(rest);
521  OBJ_FREEZE_RAW(rest);
522  if (NIL_P(name)) {
523  st = anonymous_struct(klass);
524  }
525  else {
526  st = new_struct(name, klass);
527  }
528  setup_struct(st, rest);
529  if (rb_block_given_p()) {
530  rb_mod_module_eval(0, 0, st);
531  }
532 
533  return st;
534 }
535 
536 static long
537 num_members(VALUE klass)
538 {
539  VALUE members;
540  members = struct_ivar_get(klass, id_members);
541  if (!RB_TYPE_P(members, T_ARRAY)) {
542  rb_raise(rb_eTypeError, "broken members");
543  }
544  return RARRAY_LEN(members);
545 }
546 
547 /*
548  */
549 
550 static VALUE
551 rb_struct_initialize_m(int argc, const VALUE *argv, VALUE self)
552 {
553  VALUE klass = rb_obj_class(self);
554  long i, n;
555 
556  rb_struct_modify(self);
557  n = num_members(klass);
558  if (n < argc) {
559  rb_raise(rb_eArgError, "struct size differs");
560  }
561  for (i=0; i<argc; i++) {
562  RSTRUCT_SET(self, i, argv[i]);
563  }
564  if (n > argc) {
565  rb_mem_clear((VALUE *)RSTRUCT_CONST_PTR(self)+argc, n-argc);
566  }
567  return Qnil;
568 }
569 
570 VALUE
572 {
573  return rb_struct_initialize_m(RARRAY_LENINT(values), RARRAY_CONST_PTR(values), self);
574 }
575 
576 static VALUE
577 struct_alloc(VALUE klass)
578 {
579  long n;
581 
582  n = num_members(klass);
583 
584  if (0 < n && n <= RSTRUCT_EMBED_LEN_MAX) {
585  RBASIC(st)->flags &= ~RSTRUCT_EMBED_LEN_MASK;
586  RBASIC(st)->flags |= n << RSTRUCT_EMBED_LEN_SHIFT;
587  rb_mem_clear((VALUE *)st->as.ary, n);
588  }
589  else {
590  st->as.heap.ptr = ALLOC_N(VALUE, n);
591  rb_mem_clear((VALUE *)st->as.heap.ptr, n);
592  st->as.heap.len = n;
593  }
594 
595  return (VALUE)st;
596 }
597 
598 VALUE
600 {
601  return rb_class_new_instance(RARRAY_LENINT(values), RARRAY_CONST_PTR(values), klass);
602 }
603 
604 VALUE
605 rb_struct_new(VALUE klass, ...)
606 {
607  VALUE tmpargs[N_REF_FUNC], *mem = tmpargs;
608  int size, i;
609  va_list args;
610 
611  size = rb_long2int(num_members(klass));
612  if (size > numberof(tmpargs)) {
613  tmpargs[0] = rb_ary_tmp_new(size);
614  mem = RARRAY_PTR(tmpargs[0]);
615  }
616  va_start(args, klass);
617  for (i=0; i<size; i++) {
618  mem[i] = va_arg(args, VALUE);
619  }
620  va_end(args);
621 
622  return rb_class_new_instance(size, mem, klass);
623 }
624 
625 static VALUE
626 struct_enum_size(VALUE s, VALUE args, VALUE eobj)
627 {
628  return rb_struct_size(s);
629 }
630 
631 /*
632  * call-seq:
633  * struct.each {|obj| block } -> struct
634  * struct.each -> enumerator
635  *
636  * Yields the value of each struct member in order. If no block is given an
637  * enumerator is returned.
638  *
639  * Customer = Struct.new(:name, :address, :zip)
640  * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
641  * joe.each {|x| puts(x) }
642  *
643  * Produces:
644  *
645  * Joe Smith
646  * 123 Maple, Anytown NC
647  * 12345
648  */
649 
650 static VALUE
651 rb_struct_each(VALUE s)
652 {
653  long i;
654 
655  RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
656  for (i=0; i<RSTRUCT_LEN(s); i++) {
657  rb_yield(RSTRUCT_GET(s, i));
658  }
659  return s;
660 }
661 
662 /*
663  * call-seq:
664  * struct.each_pair {|sym, obj| block } -> struct
665  * struct.each_pair -> enumerator
666  *
667  * Yields the name and value of each struct member in order. If no block is
668  * given an enumerator is returned.
669  *
670  * Customer = Struct.new(:name, :address, :zip)
671  * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
672  * joe.each_pair {|name, value| puts("#{name} => #{value}") }
673  *
674  * Produces:
675  *
676  * name => Joe Smith
677  * address => 123 Maple, Anytown NC
678  * zip => 12345
679  */
680 
681 static VALUE
682 rb_struct_each_pair(VALUE s)
683 {
684  VALUE members;
685  long i;
686 
687  RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
688  members = rb_struct_members(s);
689  if (rb_block_arity() > 1) {
690  for (i=0; i<RSTRUCT_LEN(s); i++) {
691  VALUE key = rb_ary_entry(members, i);
692  VALUE value = RSTRUCT_GET(s, i);
693  rb_yield_values(2, key, value);
694  }
695  }
696  else {
697  for (i=0; i<RSTRUCT_LEN(s); i++) {
698  VALUE key = rb_ary_entry(members, i);
699  VALUE value = RSTRUCT_GET(s, i);
700  rb_yield(rb_assoc_new(key, value));
701  }
702  }
703  return s;
704 }
705 
706 static VALUE
707 inspect_struct(VALUE s, VALUE dummy, int recur)
708 {
709  VALUE cname = rb_class_path(rb_obj_class(s));
710  VALUE members, str = rb_str_new2("#<struct ");
711  long i, len;
712  char first = RSTRING_PTR(cname)[0];
713 
714  if (recur || first != '#') {
715  rb_str_append(str, cname);
716  }
717  if (recur) {
718  return rb_str_cat2(str, ":...>");
719  }
720 
721  members = rb_struct_members(s);
722  len = RSTRUCT_LEN(s);
723 
724  for (i=0; i<len; i++) {
725  VALUE slot;
726  ID id;
727 
728  if (i > 0) {
729  rb_str_cat2(str, ", ");
730  }
731  else if (first != '#') {
732  rb_str_cat2(str, " ");
733  }
734  slot = RARRAY_AREF(members, i);
735  id = SYM2ID(slot);
736  if (rb_is_local_id(id) || rb_is_const_id(id)) {
737  rb_str_append(str, rb_id2str(id));
738  }
739  else {
740  rb_str_append(str, rb_inspect(slot));
741  }
742  rb_str_cat2(str, "=");
743  rb_str_append(str, rb_inspect(RSTRUCT_GET(s, i)));
744  }
745  rb_str_cat2(str, ">");
746  OBJ_INFECT(str, s);
747 
748  return str;
749 }
750 
751 /*
752  * call-seq:
753  * struct.to_s -> string
754  * struct.inspect -> string
755  *
756  * Returns a description of this struct as a string.
757  */
758 
759 static VALUE
760 rb_struct_inspect(VALUE s)
761 {
762  return rb_exec_recursive(inspect_struct, s, 0);
763 }
764 
765 /*
766  * call-seq:
767  * struct.to_a -> array
768  * struct.values -> array
769  *
770  * Returns the values for this struct as an Array.
771  *
772  * Customer = Struct.new(:name, :address, :zip)
773  * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
774  * joe.to_a[1] #=> "123 Maple, Anytown NC"
775  */
776 
777 static VALUE
778 rb_struct_to_a(VALUE s)
779 {
781 }
782 
783 /*
784  * call-seq:
785  * struct.to_h -> hash
786  *
787  * Returns a Hash containing the names and values for the struct's members.
788  *
789  * Customer = Struct.new(:name, :address, :zip)
790  * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
791  * joe.to_h[:address] #=> "123 Maple, Anytown NC"
792  */
793 
794 static VALUE
795 rb_struct_to_h(VALUE s)
796 {
798  VALUE members = rb_struct_members(s);
799  long i;
800 
801  for (i=0; i<RSTRUCT_LEN(s); i++) {
802  rb_hash_aset(h, rb_ary_entry(members, i), RSTRUCT_GET(s, i));
803  }
804  return h;
805 }
806 
807 /* :nodoc: */
808 VALUE
810 {
811  long i, len;
812 
813  if (!OBJ_INIT_COPY(copy, s)) return copy;
814  if (RSTRUCT_LEN(copy) != RSTRUCT_LEN(s)) {
815  rb_raise(rb_eTypeError, "struct size mismatch");
816  }
817 
818  for (i=0, len=RSTRUCT_LEN(copy); i<len; i++) {
819  RSTRUCT_SET(copy, i, RSTRUCT_GET(s, i));
820  }
821 
822  return copy;
823 }
824 
825 static int
826 rb_struct_pos(VALUE s, VALUE *name)
827 {
828  long i;
829  VALUE idx = *name;
830 
831  if (RB_TYPE_P(idx, T_SYMBOL)) {
832  return struct_member_pos(s, idx);
833  }
834  else if (RB_TYPE_P(idx, T_STRING)) {
835  idx = rb_check_symbol(name);
836  if (NIL_P(idx)) return -1;
837  return struct_member_pos(s, idx);
838  }
839  else {
840  long len;
841  i = NUM2LONG(idx);
842  len = RSTRUCT_LEN(s);
843  if (i < 0) {
844  if (i + len < 0) {
845  *name = LONG2FIX(i);
846  return -1;
847  }
848  i += len;
849  }
850  else if (len <= i) {
851  *name = LONG2FIX(i);
852  return -1;
853  }
854  return (int)i;
855  }
856 }
857 
858 NORETURN(static void invalid_struct_pos(VALUE s, VALUE idx));
859 static void
860 invalid_struct_pos(VALUE s, VALUE idx)
861 {
862  if (FIXNUM_P(idx)) {
863  long i = FIX2INT(idx), len = RSTRUCT_LEN(s);
864  if (i < 0) {
865  rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
866  i, len);
867  }
868  else {
869  rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
870  i, len);
871  }
872  }
873  else {
874  rb_name_err_raise("no member '%1$s' in struct", s, idx);
875  }
876 }
877 
878 /*
879  * call-seq:
880  * struct[member] -> object
881  * struct[index] -> object
882  *
883  * Attribute Reference---Returns the value of the given struct +member+ or
884  * the member at the given +index+. Raises NameError if the +member+ does
885  * not exist and IndexError if the +index+ is out of range.
886  *
887  * Customer = Struct.new(:name, :address, :zip)
888  * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
889  *
890  * joe["name"] #=> "Joe Smith"
891  * joe[:name] #=> "Joe Smith"
892  * joe[0] #=> "Joe Smith"
893  */
894 
895 VALUE
897 {
898  int i = rb_struct_pos(s, &idx);
899  if (i < 0) invalid_struct_pos(s, idx);
900  return RSTRUCT_GET(s, i);
901 }
902 
903 /*
904  * call-seq:
905  * struct[member] = obj -> obj
906  * struct[index] = obj -> obj
907  *
908  * Attribute Assignment---Sets the value of the given struct +member+ or
909  * the member at the given +index+. Raises NameError if the +member+ does not
910  * exist and IndexError if the +index+ is out of range.
911  *
912  * Customer = Struct.new(:name, :address, :zip)
913  * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
914  *
915  * joe["name"] = "Luke"
916  * joe[:zip] = "90210"
917  *
918  * joe.name #=> "Luke"
919  * joe.zip #=> "90210"
920  */
921 
922 VALUE
924 {
925  int i = rb_struct_pos(s, &idx);
926  if (i < 0) invalid_struct_pos(s, idx);
927  rb_struct_modify(s);
928  RSTRUCT_SET(s, i, val);
929  return val;
930 }
931 
933 NOINLINE(static VALUE rb_struct_lookup_default(VALUE s, VALUE idx, VALUE notfound));
934 
935 VALUE
937 {
938  return rb_struct_lookup_default(s, idx, Qnil);
939 }
940 
941 static VALUE
942 rb_struct_lookup_default(VALUE s, VALUE idx, VALUE notfound)
943 {
944  int i = rb_struct_pos(s, &idx);
945  if (i < 0) return notfound;
946  return RSTRUCT_GET(s, i);
947 }
948 
949 static VALUE
950 struct_entry(VALUE s, long n)
951 {
952  return rb_struct_aref(s, LONG2NUM(n));
953 }
954 
955 /*
956  * call-seq:
957  * struct.values_at(selector, ...) -> array
958  *
959  * Returns the struct member values for each +selector+ as an Array. A
960  * +selector+ may be either an Integer offset or a Range of offsets (as in
961  * Array#values_at).
962  *
963  * Customer = Struct.new(:name, :address, :zip)
964  * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
965  * joe.values_at(0, 2) #=> ["Joe Smith", 12345]
966  *
967  */
968 
969 static VALUE
970 rb_struct_values_at(int argc, VALUE *argv, VALUE s)
971 {
972  return rb_get_values_at(s, RSTRUCT_LEN(s), argc, argv, struct_entry);
973 }
974 
975 /*
976  * call-seq:
977  * struct.select {|obj| block } -> array
978  * struct.select -> enumerator
979  *
980  * Yields each member value from the struct to the block and returns an Array
981  * containing the member values from the +struct+ for which the given block
982  * returns a true value (equivalent to Enumerable#select).
983  *
984  * Lots = Struct.new(:a, :b, :c, :d, :e, :f)
985  * l = Lots.new(11, 22, 33, 44, 55, 66)
986  * l.select {|v| v.even? } #=> [22, 44, 66]
987  */
988 
989 static VALUE
990 rb_struct_select(int argc, VALUE *argv, VALUE s)
991 {
992  VALUE result;
993  long i;
994 
995  rb_check_arity(argc, 0, 0);
996  RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size);
997  result = rb_ary_new();
998  for (i = 0; i < RSTRUCT_LEN(s); i++) {
999  if (RTEST(rb_yield(RSTRUCT_GET(s, i)))) {
1000  rb_ary_push(result, RSTRUCT_GET(s, i));
1001  }
1002  }
1003 
1004  return result;
1005 }
1006 
1007 static VALUE
1008 recursive_equal(VALUE s, VALUE s2, int recur)
1009 {
1010  const VALUE *ptr, *ptr2;
1011  long i, len;
1012 
1013  if (recur) return Qtrue; /* Subtle! */
1014  ptr = RSTRUCT_CONST_PTR(s);
1015  ptr2 = RSTRUCT_CONST_PTR(s2);
1016  len = RSTRUCT_LEN(s);
1017  for (i=0; i<len; i++) {
1018  if (!rb_equal(ptr[i], ptr2[i])) return Qfalse;
1019  }
1020  return Qtrue;
1021 }
1022 
1023 /*
1024  * call-seq:
1025  * struct == other -> true or false
1026  *
1027  * Equality---Returns +true+ if +other+ has the same struct subclass and has
1028  * equal member values (according to Object#==).
1029  *
1030  * Customer = Struct.new(:name, :address, :zip)
1031  * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
1032  * joejr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
1033  * jane = Customer.new("Jane Doe", "456 Elm, Anytown NC", 12345)
1034  * joe == joejr #=> true
1035  * joe == jane #=> false
1036  */
1037 
1038 static VALUE
1039 rb_struct_equal(VALUE s, VALUE s2)
1040 {
1041  if (s == s2) return Qtrue;
1042  if (!RB_TYPE_P(s2, T_STRUCT)) return Qfalse;
1043  if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
1044  if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
1045  rb_bug("inconsistent struct"); /* should never happen */
1046  }
1047 
1048  return rb_exec_recursive_paired(recursive_equal, s, s2, s2);
1049 }
1050 
1051 /*
1052  * call-seq:
1053  * struct.hash -> integer
1054  *
1055  * Returns a hash value based on this struct's contents.
1056  *
1057  * See also Object#hash.
1058  */
1059 
1060 static VALUE
1061 rb_struct_hash(VALUE s)
1062 {
1063  long i, len;
1064  st_index_t h;
1065  VALUE n;
1066  const VALUE *ptr;
1067 
1069  ptr = RSTRUCT_CONST_PTR(s);
1070  len = RSTRUCT_LEN(s);
1071  for (i = 0; i < len; i++) {
1072  n = rb_hash(ptr[i]);
1073  h = rb_hash_uint(h, NUM2LONG(n));
1074  }
1075  h = rb_hash_end(h);
1076  return INT2FIX(h);
1077 }
1078 
1079 static VALUE
1080 recursive_eql(VALUE s, VALUE s2, int recur)
1081 {
1082  const VALUE *ptr, *ptr2;
1083  long i, len;
1084 
1085  if (recur) return Qtrue; /* Subtle! */
1086  ptr = RSTRUCT_CONST_PTR(s);
1087  ptr2 = RSTRUCT_CONST_PTR(s2);
1088  len = RSTRUCT_LEN(s);
1089  for (i=0; i<len; i++) {
1090  if (!rb_eql(ptr[i], ptr2[i])) return Qfalse;
1091  }
1092  return Qtrue;
1093 }
1094 
1095 /*
1096  * call-seq:
1097  * struct.eql?(other) -> true or false
1098  *
1099  * Hash equality---+other+ and +struct+ refer to the same hash key if they
1100  * have the same struct subclass and have equal member values (according to
1101  * Object#eql?).
1102  */
1103 
1104 static VALUE
1105 rb_struct_eql(VALUE s, VALUE s2)
1106 {
1107  if (s == s2) return Qtrue;
1108  if (!RB_TYPE_P(s2, T_STRUCT)) return Qfalse;
1109  if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
1110  if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
1111  rb_bug("inconsistent struct"); /* should never happen */
1112  }
1113 
1114  return rb_exec_recursive_paired(recursive_eql, s, s2, s2);
1115 }
1116 
1117 /*
1118  * call-seq:
1119  * struct.length -> integer
1120  * struct.size -> integer
1121  *
1122  * Returns the number of struct members.
1123  *
1124  * Customer = Struct.new(:name, :address, :zip)
1125  * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
1126  * joe.length #=> 3
1127  */
1128 
1129 VALUE
1131 {
1132  return LONG2FIX(RSTRUCT_LEN(s));
1133 }
1134 
1135 /*
1136  * call-seq:
1137  * struct.dig(key, ...) -> object
1138  *
1139  * Extracts the nested value specified by the sequence of +key+
1140  * objects by calling +dig+ at each step, returning +nil+ if any
1141  * intermediate step is +nil+.
1142  *
1143  * Foo = Struct.new(:a)
1144  * f = Foo.new(Foo.new({b: [1, 2, 3]}))
1145  *
1146  * f.dig(:a, :a, :b, 0) # => 1
1147  * f.dig(:b, 0) # => nil
1148  * f.dig(:a, :a, :b, :c) # TypeError: no implicit conversion of Symbol into Integer
1149  */
1150 
1151 static VALUE
1152 rb_struct_dig(int argc, VALUE *argv, VALUE self)
1153 {
1155  self = rb_struct_lookup(self, *argv);
1156  if (!--argc) return self;
1157  ++argv;
1158  return rb_obj_dig(argc, argv, self, Qnil);
1159 }
1160 
1161 /*
1162  * Document-class: Struct
1163  *
1164  * A Struct is a convenient way to bundle a number of attributes together,
1165  * using accessor methods, without having to write an explicit class.
1166  *
1167  * The Struct class generates new subclasses that hold a set of members and
1168  * their values. For each member a reader and writer method is created
1169  * similar to Module#attr_accessor.
1170  *
1171  * Customer = Struct.new(:name, :address) do
1172  * def greeting
1173  * "Hello #{name}!"
1174  * end
1175  * end
1176  *
1177  * dave = Customer.new("Dave", "123 Main")
1178  * dave.name #=> "Dave"
1179  * dave.greeting #=> "Hello Dave!"
1180  *
1181  * See Struct::new for further examples of creating struct subclasses and
1182  * instances.
1183  *
1184  * In the method descriptions that follow, a "member" parameter refers to a
1185  * struct member which is either a quoted string (<code>"name"</code>) or a
1186  * Symbol (<code>:name</code>).
1187  */
1188 void
1190 {
1191  rb_cStruct = rb_define_class("Struct", rb_cObject);
1193 
1195  rb_define_singleton_method(rb_cStruct, "new", rb_struct_s_def, -1);
1196 
1197  rb_define_method(rb_cStruct, "initialize", rb_struct_initialize_m, -1);
1198  rb_define_method(rb_cStruct, "initialize_copy", rb_struct_init_copy, 1);
1199 
1200  rb_define_method(rb_cStruct, "==", rb_struct_equal, 1);
1201  rb_define_method(rb_cStruct, "eql?", rb_struct_eql, 1);
1202  rb_define_method(rb_cStruct, "hash", rb_struct_hash, 0);
1203 
1204  rb_define_method(rb_cStruct, "inspect", rb_struct_inspect, 0);
1205  rb_define_alias(rb_cStruct, "to_s", "inspect");
1206  rb_define_method(rb_cStruct, "to_a", rb_struct_to_a, 0);
1207  rb_define_method(rb_cStruct, "to_h", rb_struct_to_h, 0);
1208  rb_define_method(rb_cStruct, "values", rb_struct_to_a, 0);
1211 
1212  rb_define_method(rb_cStruct, "each", rb_struct_each, 0);
1213  rb_define_method(rb_cStruct, "each_pair", rb_struct_each_pair, 0);
1216  rb_define_method(rb_cStruct, "select", rb_struct_select, -1);
1217  rb_define_method(rb_cStruct, "values_at", rb_struct_values_at, -1);
1218 
1219  rb_define_method(rb_cStruct, "members", rb_struct_members_m, 0);
1220  rb_define_method(rb_cStruct, "dig", rb_struct_dig, -1);
1221 }
1222 
1223 #undef rb_intern
1224 void
1226 {
1227  id_members = rb_intern("__members__");
1228  id_back_members = rb_intern("__members_back__");
1229 
1230  InitVM(Struct);
1231 }
#define RBASIC_CLEAR_CLASS(obj)
Definition: internal.h:1469
FUNC_MINIMIZED(VALUE rb_struct_lookup(VALUE s, VALUE idx))
#define T_SYMBOL
Definition: ruby.h:508
VALUE rb_hash(VALUE obj)
Definition: hash.c:121
NOINLINE(static VALUE rb_struct_lookup_default(VALUE s, VALUE idx, VALUE notfound))
VALUE rb_struct_s_members(VALUE klass)
Definition: struct.c:51
void rb_warn(const char *fmt,...)
Definition: error.c:246
void rb_bug(const char *fmt,...)
Definition: error.c:521
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1215
#define RARRAY_LEN(a)
Definition: ruby.h:1019
Definition: st.h:79
void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi)
Definition: vm_method.c:637
#define RSTRUCT_CONST_PTR(st)
Definition: internal.h:710
VALUE rb_yield_values(int n,...)
Definition: vm_eval.c:985
void rb_undef_alloc_func(VALUE)
Definition: vm_method.c:675
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
Definition: class.c:1716
VALUE rb_struct_define(const char *name,...)
Definition: struct.c:410
int rb_block_given_p(void)
Determines if the current method is given a block.
Definition: eval.c:835
VALUE rb_struct_initialize(VALUE self, VALUE values)
Definition: struct.c:571
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2284
#define InitVM(ext)
Definition: ruby.h:2164
VALUE rb_define_class_id_under(VALUE outer, ID id, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:716
#define Qtrue
Definition: ruby.h:437
st_index_t rb_hash_end(st_index_t)
#define OBJ_INIT_COPY(obj, orig)
Definition: intern.h:283
#define rb_id2str(id)
Definition: vm_backtrace.c:29
const int id
Definition: nkf.c:209
int rb_is_const_id(ID id)
Definition: symbol.c:820
void rb_check_trusted(VALUE obj)
Definition: error.c:2622
void rb_mem_clear(register VALUE *mem, register long size)
Definition: array.c:138
#define rb_check_arity
Definition: intern.h:298
#define UNREACHABLE
Definition: ruby.h:46
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:924
#define rb_long2int(n)
Definition: ruby.h:319
#define SYM2ID(x)
Definition: ruby.h:384
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:544
void Init_Struct(void)
Definition: struct.c:1225
VALUE rb_struct_getmember(VALUE obj, ID id)
Definition: struct.c:205
VALUE rb_struct_aset(VALUE s, VALUE idx, VALUE val)
Definition: struct.c:923
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
Definition: class.c:693
VALUE rb_exec_recursive(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE)
Definition: thread.c:4709
void rb_define_alloc_func(VALUE, rb_alloc_func_t)
VALUE rb_struct_alloc(VALUE klass, VALUE values)
Definition: struct.c:599
void InitVM_Struct(void)
Definition: struct.c:1189
void rb_include_module(VALUE klass, VALUE module)
Definition: class.c:864
#define T_ARRAY
Definition: ruby.h:498
st_data_t st_index_t
Definition: st.h:50
#define FIXNUM_P(f)
Definition: ruby.h:365
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
Definition: object.c:656
VALUE rb_hash_new_with_size(st_index_t size)
Definition: hash.c:430
#define rb_name_err_raise(mesg, recv, name)
Definition: internal.h:1168
#define RHASH_TBL(h)
Definition: ruby.h:1056
VALUE rb_eArgError
Definition: error.c:802
VALUE rb_hash_keys(VALUE hash)
Definition: hash.c:2131
#define sym(x)
Definition: date_core.c:3721
NORETURN(static void invalid_struct_pos(VALUE s, VALUE idx))
#define NEWOBJ_OF(obj, type, klass, flags)
Definition: ruby.h:754
VALUE rb_struct_aref(VALUE s, VALUE idx)
Definition: struct.c:896
VALUE rb_obj_class(VALUE)
call-seq: obj.class -> class
Definition: object.c:277
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
#define UNLIKELY(x)
Definition: internal.h:43
VALUE rb_get_values_at(VALUE obj, long olen, int argc, const VALUE *argv, VALUE(*func)(VALUE, long))
Definition: array.c:2789
VALUE rb_class_inherited(VALUE super, VALUE klass)
Calls Class::inherited.
Definition: class.c:620
#define RGENGC_WB_PROTECTED_STRUCT
Definition: ruby.h:777
VALUE rb_equal(VALUE, VALUE)
call-seq: obj === other -> true or false
Definition: object.c:126
#define ALLOC_N(type, n)
Definition: ruby.h:1587
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:1616
#define val
RUBY_EXTERN VALUE rb_cObject
Definition: ruby.h:1893
VALUE rb_exec_recursive_paired(VALUE(*)(VALUE, VALUE, int), VALUE, VALUE, VALUE)
Definition: thread.c:4720
VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound)
Definition: object.c:3699
VALUE rb_str_cat2(VALUE, const char *)
VALUE rb_ary_new(void)
Definition: array.c:499
#define RSTRUCT_LEN(st)
Definition: ruby.h:1186
VALUE rb_eIndexError
Definition: error.c:803
#define NIL_P(v)
Definition: ruby.h:451
VALUE rb_define_class(const char *name, VALUE super)
Defines a top-level class.
Definition: class.c:646
VALUE rb_struct_define_without_accessor_under(VALUE outer, const char *class_name, VALUE super, rb_alloc_func_t alloc,...)
Definition: struct.c:384
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:815
#define ID_SCOPE_SHIFT
Definition: id.h:31
int argc
Definition: ruby.c:187
char ary[RSTRING_EMBED_LEN_MAX+1]
Definition: ruby.h:965
#define Qfalse
Definition: ruby.h:436
VALUE rb_struct_define_under(VALUE outer, const char *name,...)
Definition: struct.c:425
#define rb_ary_new4
Definition: intern.h:92
#define rb_str_new2
Definition: intern.h:835
#define OBJ_FREEZE_RAW(x)
Definition: ruby.h:1305
VALUE rb_struct_new(VALUE klass,...)
Definition: struct.c:605
#define numberof(array)
Definition: etc.c:618
void rb_define_alias(VALUE klass, const char *name1, const char *name2)
Defines an alias of a method.
Definition: class.c:1758
VALUE rb_yield(VALUE)
Definition: vm_eval.c:973
#define RARRAY_CONST_PTR(a)
Definition: ruby.h:1021
VALUE rb_mEnumerable
Definition: enum.c:19
int rb_is_const_name(VALUE name)
Definition: symbol.c:1076
VALUE rb_to_symbol(VALUE name)
Definition: string.c:10506
VALUE rb_class_path(VALUE)
Definition: variable.c:295
VALUE rb_mod_module_eval(int, const VALUE *, VALUE)
Definition: vm_eval.c:1748
VALUE rb_struct_size(VALUE s)
Definition: struct.c:1130
VALUE rb_ivar_set(VALUE, ID, VALUE)
Definition: variable.c:1315
VALUE rb_assoc_new(VALUE car, VALUE cdr)
Definition: array.c:639
#define PRIsVALUE
Definition: ruby.h:135
unsigned long ID
Definition: ruby.h:86
int rb_block_arity(void)
Definition: proc.c:1036
VALUE rb_cStruct
Definition: struct.c:25
#define T_STRUCT
Definition: ruby.h:500
#define Qnil
Definition: ruby.h:438
rb_control_frame_t *FUNC_FASTCALL() rb_vm_opt_struct_aref(rb_thread_t *th, rb_control_frame_t *reg_cfp)
unsigned long VALUE
Definition: ruby.h:85
#define RETURN_SIZED_ENUMERATOR(obj, argc, argv, size_fn)
Definition: intern.h:234
#define RBASIC(obj)
Definition: ruby.h:1197
VALUE rb_struct_define_without_accessor(const char *class_name, VALUE super, rb_alloc_func_t alloc,...)
Definition: struct.c:397
VALUE rb_eTypeError
Definition: error.c:801
#define FIX2INT(x)
Definition: ruby.h:686
const rb_iseq_t * rb_method_for_self_aset(VALUE name, VALUE arg, rb_insn_func_t func)
Definition: compile.c:7621
VALUE rb_make_metaclass(VALUE obj, VALUE unused)
Definition: class.c:577
#define RARRAY_LENINT(ary)
Definition: ruby.h:1020
#define N_REF_FUNC
Definition: struct.c:228
VALUE rb_sym_intern_ascii_cstr(const char *ptr)
Definition: symbol.c:1042
#define LONG2NUM(x)
Definition: ruby.h:1573
register unsigned int len
Definition: zonetab.h:51
#define recur(fmt)
#define RSTRUCT_SET(st, idx, v)
Definition: ruby.h:1188
#define RSTRING_PTR(str)
Definition: ruby.h:975
int rb_const_defined_at(VALUE, ID)
Definition: variable.c:2543
void rb_define_method_id(VALUE klass, ID mid, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1509
int size
Definition: encoding.c:57
VALUE rb_ident_hash_new(void)
Definition: hash.c:2924
#define RSTRUCT_GET(st, idx)
Definition: ruby.h:1189
#define INT2FIX(i)
Definition: ruby.h:232
#define UNLIMITED_ARGUMENTS
Definition: intern.h:44
#define RCLASS_SUPER(c)
Definition: classext.h:16
#define RARRAY_AREF(a, i)
Definition: ruby.h:1033
#define FUNC_FASTCALL(x)
Definition: vm_core.h:998
#define RARRAY_PTR(a)
Definition: ruby.h:1041
const rb_iseq_t * rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func)
Definition: compile.c:7612
#define FL_WB_PROTECTED
Definition: ruby.h:1209
rb_control_frame_t *FUNC_FASTCALL rb_insn_func_t(rb_thread_t *, rb_control_frame_t *)
Definition: vm_core.h:1002
#define LONG2FIX(i)
Definition: ruby.h:234
#define RTEST(v)
Definition: ruby.h:450
#define T_STRING
Definition: ruby.h:496
VALUE rb_mod_remove_const(VALUE, VALUE)
Definition: variable.c:2332
VALUE rb_class_new_instance(int, const VALUE *, VALUE)
Allocates and initializes an instance of klass.
Definition: object.c:2170
st_index_t rb_hash_uint(st_index_t, st_index_t)
struct rb_encoding_entry * list
Definition: encoding.c:55
#define OBJ_INFECT(x, s)
Definition: ruby.h:1302
VALUE rb_ary_dup(VALUE ary)
Definition: array.c:1930
int rb_is_local_id(ID id)
Definition: symbol.c:850
VALUE rb_check_symbol(volatile VALUE *namep)
Definition: symbol.c:948
#define st_insert
Definition: regint.h:184
const char * name
Definition: nkf.c:208
#define ID2SYM(x)
Definition: ruby.h:383
int rb_eql(VALUE, VALUE)
Determines if obj1 and obj2 are equal in terms of Object::eql?.
Definition: object.c:149
VALUE rb_struct_alloc_noinit(VALUE klass)
Definition: struct.c:328
VALUE rb_struct_members(VALUE s)
Definition: struct.c:65
void st_clear(st_table *)
Definition: st.c:655
#define rb_check_frozen(obj)
Definition: intern.h:271
rb_control_frame_t *FUNC_FASTCALL() rb_vm_opt_struct_aset(rb_thread_t *th, rb_control_frame_t *reg_cfp)
ID rb_id_attrset(ID)
Definition: symbol.c:100
#define rb_intern(str)
#define SYMBOL_P(x)
Definition: ruby.h:382
VALUE(* rb_alloc_func_t)(VALUE)
Definition: intern.h:370
#define NULL
Definition: _sdbm.c:102
VALUE rb_struct_lookup(VALUE s, VALUE idx)
Definition: struct.c:936
VALUE rb_class_new(VALUE super)
Creates a new class.
Definition: class.c:242
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2900
VALUE rb_str_to_str(VALUE)
Definition: string.c:1349
ID rb_to_id(VALUE)
Definition: string.c:10496
#define NUM2LONG(x)
Definition: ruby.h:648
st_index_t rb_hash_start(st_index_t)
Definition: random.c:1506
VALUE rb_attr_get(VALUE, ID)
Definition: variable.c:1224
char ** argv
Definition: ruby.c:188
char * ptr
Definition: ruby.h:959
VALUE rb_struct_init_copy(VALUE copy, VALUE s)
Definition: struct.c:809