Skip to content
Newer
Older
100644 967 lines (858 sloc) 23.7 KB
9595725 update copyrights to 2011
Laurent Sansonetti authored
1 /*
2 * This file is covered by the Ruby license. See COPYING for more details.
7d7d3e8 @ferrous26 Change ownership to The MacRuby Team and update copyrights
ferrous26 authored
3 *
4 * Copyright (C) 2012, The MacRuby Team. All rights reserved.
9595725 update copyrights to 2011
Laurent Sansonetti authored
5 * Copyright (C) 2007-2011, Apple Inc. All rights reserved.
6 * Copyright (C) 1993-2007 Yukihiro Matsumoto
7 */
9c1d230 committing experimental branch content
Laurent Sansonetti authored
8
d0898dd include/ruby/macruby.h -> macruby_internal.h
Laurent Sansonetti authored
9 #include "macruby_internal.h"
9c1d230 committing experimental branch content
Laurent Sansonetti authored
10 #include "ruby/node.h"
cb65416 the great schism, part I
Laurent Sansonetti authored
11 #include "vm.h"
d0e13a1 move internal stuff from the public headers
Laurent Sansonetti authored
12 #include "class.h"
9c1d230 committing experimental branch content
Laurent Sansonetti authored
13
14 VALUE rb_cStruct;
b2b73dd @Watson1978 cache symbol to reduce calls to rb_intern()
Watson1978 authored
15 static ID id_members;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
16
17 static VALUE struct_alloc(VALUE);
18
b2b73dd @Watson1978 cache symbol to reduce calls to rb_intern()
Watson1978 authored
19 static inline VALUE
20 struct_ivar_get(VALUE c, ID id)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
21 {
22 for (;;) {
23 if (rb_ivar_defined(c, id))
24 return rb_ivar_get(c, id);
25 c = RCLASS_SUPER(c);
26 if (c == 0 || c == rb_cStruct)
27 return Qnil;
28 }
29 }
30
31 VALUE
b2b73dd @Watson1978 cache symbol to reduce calls to rb_intern()
Watson1978 authored
32 rb_struct_iv_get(VALUE c, const char *name)
33 {
34 return struct_ivar_get(c, rb_intern(name));
35 }
36
37 VALUE
9c1d230 committing experimental branch content
Laurent Sansonetti authored
38 rb_struct_s_members(VALUE klass)
39 {
b2b73dd @Watson1978 cache symbol to reduce calls to rb_intern()
Watson1978 authored
40 VALUE members = struct_ivar_get(klass, id_members);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
41
42 if (NIL_P(members)) {
43 rb_raise(rb_eTypeError, "uninitialized struct");
44 }
45 if (TYPE(members) != T_ARRAY) {
46 rb_raise(rb_eTypeError, "corrupted struct");
47 }
48 return members;
49 }
50
51 VALUE
52 rb_struct_members(VALUE s)
53 {
54 VALUE members = rb_struct_s_members(rb_obj_class(s));
55
56 if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) {
57 rb_raise(rb_eTypeError, "struct size differs (%ld required %ld given)",
58 RARRAY_LEN(members), RSTRUCT_LEN(s));
59 }
60 return members;
61 }
62
63 static VALUE
64 rb_struct_s_members_m(VALUE klass)
65 {
66 #if WITH_OBJC
67 return rb_ary_dup(rb_struct_s_members(klass));
68 #else
69 VALUE members, ary;
70 VALUE *p, *pend;
71
72 members = rb_struct_s_members(klass);
73 ary = rb_ary_new2(RARRAY_LEN(members));
74 p = RARRAY_PTR(members); pend = p + RARRAY_LEN(members);
75 while (p < pend) {
76 rb_ary_push(ary, *p);
77 p++;
78 }
79
80 return ary;
81 #endif
82 }
83
84 /*
85 * call-seq:
7bd034f @Watson1978 update rdoc
Watson1978 authored
86 * struct.members -> array
87 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
88 * Returns an array of strings representing the names of the instance
89 * variables.
7bd034f @Watson1978 update rdoc
Watson1978 authored
90 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
91 * Customer = Struct.new(:name, :address, :zip)
92 * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
93 * joe.members #=> [:name, :address, :zip]
94 */
95
96 static VALUE
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
97 rb_struct_members_m(VALUE obj, SEL sel)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
98 {
99 return rb_struct_s_members_m(rb_obj_class(obj));
100 }
101
102 VALUE
103 rb_struct_getmember(VALUE obj, ID id)
104 {
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
105 VALUE members, slot, *ptr;
106 long i, len;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
107
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
108 ptr = RSTRUCT_PTR(obj);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
109 members = rb_struct_members(obj);
110 slot = ID2SYM(id);
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
111 len = RARRAY_LEN(members);
112 for (i=0; i<len; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
113 if (RARRAY_AT(members, i) == slot) {
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
114 return ptr[i];
9c1d230 committing experimental branch content
Laurent Sansonetti authored
115 }
116 }
117 rb_name_error(id, "%s is not struct member", rb_id2name(id));
118 return Qnil; /* not reached */
119 }
120
121 static void
122 rb_struct_modify(VALUE s)
123 {
124 if (OBJ_FROZEN(s)) rb_error_frozen("Struct");
125 if (!OBJ_TAINTED(s) && rb_safe_level() >= 4)
126 rb_raise(rb_eSecurityError, "Insecure: can't modify Struct");
127 }
128
129 static VALUE
130 make_struct(VALUE name, VALUE members, VALUE klass)
131 {
132 VALUE nstr;
133 ID id;
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
134 long i, len;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
135
136 OBJ_FREEZE(members);
137 if (NIL_P(name)) {
138 nstr = rb_class_new(klass);
139 #if !WITH_OBJC
140 rb_make_metaclass(nstr, RBASIC(klass)->klass);
141 #endif
142 rb_class_inherited(klass, nstr);
143 }
144 else {
145 /* old style: should we warn? */
146 name = rb_str_to_str(name);
147 id = rb_to_id(name);
148 if (!rb_is_const_id(id)) {
4d321d1 fixed several bugs in the Struct class, now it's usable again
Laurent Sansonetti authored
149 rb_name_error(id, "identifier %s needs to be constant",
150 StringValuePtr(name));
9c1d230 committing experimental branch content
Laurent Sansonetti authored
151 }
152 if (rb_const_defined_at(klass, id)) {
153 rb_warn("redefining constant Struct::%s", StringValuePtr(name));
154 rb_mod_remove_const(klass, ID2SYM(id));
155 }
156 nstr = rb_define_class_under(klass, rb_id2name(id), klass);
157 }
b2b73dd @Watson1978 cache symbol to reduce calls to rb_intern()
Watson1978 authored
158 rb_ivar_set(nstr, id_members, members);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
159
a8de550 more porting to rb_objc_define_method()
Laurent Sansonetti authored
160 rb_objc_define_method(*(VALUE *)nstr, "alloc", struct_alloc, 0);
4d321d1 fixed several bugs in the Struct class, now it's usable again
Laurent Sansonetti authored
161 rb_objc_define_method(*(VALUE *)nstr, "new", rb_class_new_instance_imp, -1);
162 rb_objc_define_method(*(VALUE *)nstr, "[]", rb_class_new_instance_imp, -1);
a8de550 more porting to rb_objc_define_method()
Laurent Sansonetti authored
163 rb_objc_define_method(*(VALUE *)nstr, "members", rb_struct_s_members_m, 0);
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
164 len = RARRAY_LEN(members);
165 for (i=0; i< len; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
166 ID id = SYM2ID(RARRAY_AT(members, i));
167 if (rb_is_local_id(id) || rb_is_const_id(id)) {
0625753 @macrotis Clean up additions to struct.c to match MacRuby coding guidelines
macrotis authored
168 long j = i; /* Needed for block data reference. */
3c06b54 @macrotis Follow MacRuby style guidelines with stack-passing blocks in struct.c
macrotis authored
169 /* Struct attribute reader */
170 rb_objc_define_method(nstr, rb_id2name(id),
171 pl_imp_implementationWithBlock(^(VALUE obj) {
172 return RSTRUCT_PTR(obj)[j];
173 }), 0);
174 /* Struct attribute writer */
175 rb_objc_define_method(nstr, rb_id2name(rb_id_attrset(id)),
176 pl_imp_implementationWithBlock(^(VALUE obj, VALUE val) {
177 VALUE *ptr = RSTRUCT_PTR(obj);
178 rb_struct_modify(obj);
179 GC_WB(&ptr[i], val);
180 return val;
181 }), 1);
e80a075 @macrotis Pass block environments to pl_imp_implementationWithBlock() directly …
macrotis authored
182 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
183 }
184
185 return nstr;
186 }
187
188 VALUE
189 rb_struct_alloc_noinit(VALUE klass)
190 {
191 return struct_alloc(klass);
192 }
193
194 VALUE
195 rb_struct_define_without_accessor(const char *class_name, VALUE super, rb_alloc_func_t alloc, ...)
196 {
197 VALUE klass;
198 va_list ar;
199 VALUE members;
200 long i;
201 char *name;
202
203 members = rb_ary_new2(0);
204 va_start(ar, alloc);
205 i = 0;
206 while ((name = va_arg(ar, char*)) != NULL) {
207 rb_ary_push(members, ID2SYM(rb_intern(name)));
208 }
209 va_end(ar);
210 OBJ_FREEZE(members);
211
212 if (class_name) {
213 klass = rb_define_class(class_name, super);
214 }
215 else {
216 klass = rb_class_new(super);
217 rb_make_metaclass(klass, RBASIC(super)->klass);
218 rb_class_inherited(super, klass);
219 }
220
b2b73dd @Watson1978 cache symbol to reduce calls to rb_intern()
Watson1978 authored
221 rb_ivar_set(klass, id_members, members);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
222
a8de550 more porting to rb_objc_define_method()
Laurent Sansonetti authored
223 rb_objc_define_method(*(VALUE *)klass, "alloc",
224 alloc != NULL ? alloc : struct_alloc,
225 0);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
226
227 return klass;
228 }
229
230 VALUE
231 rb_struct_define(const char *name, ...)
232 {
233 va_list ar;
234 VALUE nm, ary;
235 char *mem;
236
237 if (!name) nm = Qnil;
238 else nm = rb_str_new2(name);
239 ary = rb_ary_new();
240
241 va_start(ar, name);
242 while ((mem = va_arg(ar, char*)) != 0) {
243 ID slot = rb_intern(mem);
244 rb_ary_push(ary, ID2SYM(slot));
245 }
246 va_end(ar);
247
248 return make_struct(nm, ary, rb_cStruct);
249 }
250
251 /*
252 * call-seq:
7bd034f @Watson1978 update rdoc
Watson1978 authored
253 * Struct.new( [aString] [, aSym]+> ) -> StructClass
254 * StructClass.new(arg, ...) -> obj
255 * StructClass[arg, ...] -> obj
9c1d230 committing experimental branch content
Laurent Sansonetti authored
256 *
257 * Creates a new class, named by <i>aString</i>, containing accessor
258 * methods for the given symbols. If the name <i>aString</i> is
259 * omitted, an anonymous structure class will be created. Otherwise,
260 * the name of this struct will appear as a constant in class
261 * <code>Struct</code>, so it must be unique for all
262 * <code>Struct</code>s in the system and should start with a capital
263 * letter. Assigning a structure class to a constant effectively gives
264 * the class the name of the constant.
7bd034f @Watson1978 update rdoc
Watson1978 authored
265 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
266 * <code>Struct::new</code> returns a new <code>Class</code> object,
267 * which can then be used to create specific instances of the new
268 * structure. The number of actual parameters must be
269 * less than or equal to the number of attributes defined for this
7bd034f @Watson1978 update rdoc
Watson1978 authored
270 * class; unset parameters default to <code>nil</code>. Passing too many
271 * parameters will raise an <code>ArgumentError</code>.
9c1d230 committing experimental branch content
Laurent Sansonetti authored
272 *
273 * The remaining methods listed in this section (class and instance)
7bd034f @Watson1978 update rdoc
Watson1978 authored
274 * are defined for this generated class.
275 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
276 * # Create a structure with a name in Struct
277 * Struct.new("Customer", :name, :address) #=> Struct::Customer
278 * Struct::Customer.new("Dave", "123 Main") #=> #<struct Struct::Customer name="Dave", address="123 Main">
7bd034f @Watson1978 update rdoc
Watson1978 authored
279 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
280 * # Create a structure named by its constant
281 * Customer = Struct.new(:name, :address) #=> Customer
282 * Customer.new("Dave", "123 Main") #=> #<struct Customer name="Dave", address="123 Main">
283 */
284
285 VALUE rb_mod_module_eval(VALUE mod, SEL sel, int argc, VALUE *argv);
286
287 static VALUE
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
288 rb_struct_s_def(VALUE klass, SEL sel, int argc, VALUE *argv)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
289 {
290 VALUE name, rest;
4d321d1 fixed several bugs in the Struct class, now it's usable again
Laurent Sansonetti authored
291 long i, count;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
292 VALUE st;
293 ID id;
294
295 rb_scan_args(argc, argv, "1*", &name, &rest);
296 if (!NIL_P(name) && SYMBOL_P(name)) {
297 rb_ary_unshift(rest, name);
298 name = Qnil;
299 }
4d321d1 fixed several bugs in the Struct class, now it's usable again
Laurent Sansonetti authored
300 for (i = 0, count = RARRAY_LEN(rest); i < count; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
301 id = rb_to_id(RARRAY_AT(rest, i));
302 rb_ary_store(rest, i, ID2SYM(id));
303 }
304 st = make_struct(name, rest, klass);
305 if (rb_block_given_p()) {
306 rb_mod_module_eval(st, 0, 0, 0);
307 }
308
309 return st;
310 }
311
29a5f63 @Watson1978 __size__ removed. use the length of __members__ instead
Watson1978 authored
312 static long
313 num_members(VALUE klass)
314 {
315 VALUE members;
b2b73dd @Watson1978 cache symbol to reduce calls to rb_intern()
Watson1978 authored
316 members = struct_ivar_get(klass, id_members);
29a5f63 @Watson1978 __size__ removed. use the length of __members__ instead
Watson1978 authored
317 if (TYPE(members) != T_ARRAY) {
318 rb_raise(rb_eTypeError, "broken members");
319 }
320 return RARRAY_LEN(members);
321 }
322
9c1d230 committing experimental branch content
Laurent Sansonetti authored
323 /*
324 */
325
326 VALUE
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
327 rb_struct_initialize(VALUE self, SEL sel, VALUE values)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
328 {
329 VALUE klass = rb_obj_class(self);
330 long n;
331
332 rb_struct_modify(self);
29a5f63 @Watson1978 __size__ removed. use the length of __members__ instead
Watson1978 authored
333 n = num_members(klass);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
334 if (n < RARRAY_LEN(values)) {
335 rb_raise(rb_eArgError, "struct size differs");
336 }
a4117f9 adding missing write barriers
Laurent Sansonetti authored
337 for (int i = 0; i < RARRAY_LEN(values); i++) {
338 GC_WB(&RSTRUCT_PTR(self)[i], RARRAY_AT(values, i));
339 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
340 if (n > RARRAY_LEN(values)) {
a4117f9 adding missing write barriers
Laurent Sansonetti authored
341 for (int i = RARRAY_LEN(values); i < n; i++) {
342 RSTRUCT_PTR(self)[i] = Qnil;
343 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
344 }
345 return Qnil;
346 }
347
348 static VALUE
349 struct_alloc(VALUE klass)
350 {
351 long n;
352 NEWOBJ(st, struct RStruct);
353 OBJSETUP(st, klass, T_STRUCT);
354
29a5f63 @Watson1978 __size__ removed. use the length of __members__ instead
Watson1978 authored
355 n = num_members(klass);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
356
357 if (0 < n && n <= RSTRUCT_EMBED_LEN_MAX) {
358 RBASIC(st)->flags &= ~RSTRUCT_EMBED_LEN_MASK;
359 RBASIC(st)->flags |= n << RSTRUCT_EMBED_LEN_SHIFT;
360 rb_mem_clear(st->as.ary, n);
361 }
362 else {
d563cf0 avoid calling xmalloc() with a zero size (fixes several performance p…
Laurent Sansonetti authored
363 if (n > 0) {
364 GC_WB(&st->as.heap.ptr, xmalloc_ptrs(sizeof(VALUE) * n));
365 rb_mem_clear(st->as.heap.ptr, n);
366 }
367 else {
368 st->as.heap.ptr = NULL;
369 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
370 st->as.heap.len = n;
371 }
372
373 return (VALUE)st;
374 }
375
376 VALUE
377 rb_struct_alloc(VALUE klass, VALUE values)
378 {
379 return rb_class_new_instance(RARRAY_LEN(values), (VALUE *)RARRAY_PTR(values), klass);
380 }
381
382 VALUE
383 rb_struct_new(VALUE klass, ...)
384 {
29a5f63 @Watson1978 __size__ removed. use the length of __members__ instead
Watson1978 authored
385 VALUE *mem;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
386 long size, i;
387 va_list args;
388
29a5f63 @Watson1978 __size__ removed. use the length of __members__ instead
Watson1978 authored
389 size = num_members(klass);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
390 mem = ALLOCA_N(VALUE, size);
391 va_start(args, klass);
392 for (i=0; i<size; i++) {
393 mem[i] = va_arg(args, VALUE);
394 }
395 va_end(args);
396
397 return rb_class_new_instance(size, mem, klass);
398 }
399
400 /*
401 * call-seq:
7bd034f @Watson1978 update rdoc
Watson1978 authored
402 * struct.each {|obj| block } -> struct
403 * struct.each -> an_enumerator
404 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
405 * Calls <i>block</i> once for each instance variable, passing the
406 * value as a parameter.
7bd034f @Watson1978 update rdoc
Watson1978 authored
407 *
408 * If no block is given, an enumerator is returned instead.
409 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
410 * Customer = Struct.new(:name, :address, :zip)
411 * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
412 * joe.each {|x| puts(x) }
7bd034f @Watson1978 update rdoc
Watson1978 authored
413 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
414 * <em>produces:</em>
7bd034f @Watson1978 update rdoc
Watson1978 authored
415 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
416 * Joe Smith
417 * 123 Maple, Anytown NC
418 * 12345
419 */
420
421 static VALUE
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
422 rb_struct_each(VALUE s, SEL sel)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
423 {
424 long i;
425
426 RETURN_ENUMERATOR(s, 0, 0);
427 for (i=0; i<RSTRUCT_LEN(s); i++) {
428 rb_yield(RSTRUCT_PTR(s)[i]);
429 RETURN_IF_BROKEN();
430 }
431 return s;
432 }
433
434 /*
435 * call-seq:
7bd034f @Watson1978 update rdoc
Watson1978 authored
436 * struct.each_pair {|sym, obj| block } -> struct
437 * struct.each_pair -> an_enumerator
438 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
439 * Calls <i>block</i> once for each instance variable, passing the name
440 * (as a symbol) and the value as parameters.
7bd034f @Watson1978 update rdoc
Watson1978 authored
441 *
442 * If no block is given, an enumerator is returned instead.
443 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
444 * Customer = Struct.new(:name, :address, :zip)
445 * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
446 * joe.each_pair {|name, value| puts("#{name} => #{value}") }
7bd034f @Watson1978 update rdoc
Watson1978 authored
447 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
448 * <em>produces:</em>
7bd034f @Watson1978 update rdoc
Watson1978 authored
449 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
450 * name => Joe Smith
451 * address => 123 Maple, Anytown NC
452 * zip => 12345
453 */
454
455 static VALUE
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
456 rb_struct_each_pair(VALUE s, SEL sel)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
457 {
458 VALUE members;
459 long i;
460
461 RETURN_ENUMERATOR(s, 0, 0);
462 members = rb_struct_members(s);
463 for (i=0; i<RSTRUCT_LEN(s); i++) {
464 rb_yield_values(2, rb_ary_entry(members, i), RSTRUCT_PTR(s)[i]);
465 RETURN_IF_BROKEN();
466 }
467 return s;
468 }
469
470 static VALUE
471 inspect_struct(VALUE s, VALUE dummy, int recur)
472 {
473 const char *cname = rb_class2name(rb_obj_class(s));
474 VALUE str, members;
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
475 VALUE *ptr;
476 long i, len;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
477
478 if (recur) {
479 return rb_sprintf("#<struct %s:...>", cname);
480 }
481
482 members = rb_struct_members(s);
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
483 ptr = RSTRUCT_PTR(s);
484 len = RSTRUCT_LEN(s);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
485 if (cname[0] == '#') {
486 str = rb_str_new2("#<struct ");
487 }
488 else {
489 str = rb_sprintf("#<struct %s ", cname);
490 }
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
491 for (i=0; i<len; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
492 VALUE slot;
493 ID id;
494
495 if (i > 0) {
496 rb_str_cat2(str, ", ");
497 }
498 slot = RARRAY_AT(members, i);
499 id = SYM2ID(slot);
500 if (rb_is_local_id(id) || rb_is_const_id(id)) {
4d321d1 fixed several bugs in the Struct class, now it's usable again
Laurent Sansonetti authored
501 rb_str_buf_append(str, rb_id2str(id));
9c1d230 committing experimental branch content
Laurent Sansonetti authored
502 }
503 else {
4d321d1 fixed several bugs in the Struct class, now it's usable again
Laurent Sansonetti authored
504 rb_str_buf_append(str, rb_inspect(slot));
9c1d230 committing experimental branch content
Laurent Sansonetti authored
505 }
506 rb_str_cat2(str, "=");
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
507 rb_str_buf_append(str, rb_inspect(ptr[i]));
9c1d230 committing experimental branch content
Laurent Sansonetti authored
508 }
509 rb_str_cat2(str, ">");
510 OBJ_INFECT(str, s);
511
512 return str;
513 }
514
515 /*
516 * call-seq:
7bd034f @Watson1978 update rdoc
Watson1978 authored
517 * struct.to_s -> string
518 * struct.inspect -> string
9c1d230 committing experimental branch content
Laurent Sansonetti authored
519 *
520 * Describe the contents of this struct in a string.
521 */
522
523 static VALUE
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
524 rb_struct_inspect(VALUE s, SEL sel)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
525 {
526 return rb_exec_recursive(inspect_struct, s, 0);
527 }
528
529 /*
530 * call-seq:
7bd034f @Watson1978 update rdoc
Watson1978 authored
531 * struct.to_a -> array
532 * struct.values -> array
533 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
534 * Returns the values for this instance as an array.
7bd034f @Watson1978 update rdoc
Watson1978 authored
535 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
536 * Customer = Struct.new(:name, :address, :zip)
537 * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
538 * joe.to_a[1] #=> "123 Maple, Anytown NC"
539 */
540
541 static VALUE
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
542 rb_struct_to_a(VALUE s, SEL sel)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
543 {
544 return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_PTR(s));
545 }
546
547 /* :nodoc: */
ddc38dd @Watson1978 implement Range#initialize_copy
Watson1978 authored
548 VALUE
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
549 rb_struct_init_copy(VALUE copy, SEL sel, VALUE s)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
550 {
551 if (copy == s) return copy;
552 rb_check_frozen(copy);
553 if (!rb_obj_is_instance_of(s, rb_obj_class(copy))) {
554 rb_raise(rb_eTypeError, "wrong argument class");
555 }
556 if (RSTRUCT_LEN(copy) != RSTRUCT_LEN(s)) {
557 rb_raise(rb_eTypeError, "struct size mismatch");
558 }
a4117f9 adding missing write barriers
Laurent Sansonetti authored
559 for (int i = 0; i < RSTRUCT_LEN(copy); i++) {
560 GC_WB(&RSTRUCT_PTR(copy)[i], RSTRUCT_PTR(s)[i]);
561 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
562
563 return copy;
564 }
565
566 static VALUE
567 rb_struct_aref_id(VALUE s, ID id)
568 {
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
569 VALUE *ptr, members;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
570 long i, len;
571
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
572 ptr = RSTRUCT_PTR(s);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
573 members = rb_struct_members(s);
574 len = RARRAY_LEN(members);
575 for (i=0; i<len; i++) {
576 if (SYM2ID(RARRAY_AT(members, i)) == id) {
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
577 return ptr[i];
9c1d230 committing experimental branch content
Laurent Sansonetti authored
578 }
579 }
580 rb_name_error(id, "no member '%s' in struct", rb_id2name(id));
581 return Qnil; /* not reached */
582 }
583
584 /*
585 * call-seq:
7bd034f @Watson1978 update rdoc
Watson1978 authored
586 * struct[symbol] -> anObject
587 * struct[fixnum] -> anObject
588 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
589 * Attribute Reference---Returns the value of the instance variable
590 * named by <i>symbol</i>, or indexed (0..length-1) by
591 * <i>fixnum</i>. Will raise <code>NameError</code> if the named
592 * variable does not exist, or <code>IndexError</code> if the index is
593 * out of range.
7bd034f @Watson1978 update rdoc
Watson1978 authored
594 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
595 * Customer = Struct.new(:name, :address, :zip)
596 * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
7bd034f @Watson1978 update rdoc
Watson1978 authored
597 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
598 * joe["name"] #=> "Joe Smith"
599 * joe[:name] #=> "Joe Smith"
600 * joe[0] #=> "Joe Smith"
601 */
602
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
603 static VALUE
604 rb_struct_aref_imp(VALUE s, SEL sel, VALUE idx)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
605 {
606 long i;
607
608 if (TYPE(idx) == T_STRING || TYPE(idx) == T_SYMBOL) {
609 return rb_struct_aref_id(s, rb_to_id(idx));
610 }
611
612 i = NUM2LONG(idx);
613 if (i < 0) i = RSTRUCT_LEN(s) + i;
614 if (i < 0)
615 rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
616 i, RSTRUCT_LEN(s));
617 if (RSTRUCT_LEN(s) <= i)
618 rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
619 i, RSTRUCT_LEN(s));
620 return RSTRUCT_PTR(s)[i];
621 }
622
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
623 VALUE
624 rb_struct_aref(VALUE s, VALUE idx)
625 {
626 return rb_struct_aref_imp(s, 0, idx);
627 }
628
9c1d230 committing experimental branch content
Laurent Sansonetti authored
629 static VALUE
630 rb_struct_aset_id(VALUE s, ID id, VALUE val)
631 {
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
632 VALUE members, *ptr;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
633 long i, len;
634
635 members = rb_struct_members(s);
636 len = RARRAY_LEN(members);
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
637 rb_struct_modify(s);
638 if (RSTRUCT_LEN(s) != len) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
639 rb_raise(rb_eTypeError, "struct size differs (%ld required %ld given)",
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
640 len, RSTRUCT_LEN(s));
9c1d230 committing experimental branch content
Laurent Sansonetti authored
641 }
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
642 ptr = RSTRUCT_PTR(s);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
643 for (i=0; i<len; i++) {
644 if (SYM2ID(RARRAY_AT(members, i)) == id) {
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
645 GC_WB(&ptr[i], val);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
646 return val;
647 }
648 }
649 rb_name_error(id, "no member '%s' in struct", rb_id2name(id));
650 }
651
652 /*
653 * call-seq:
7bd034f @Watson1978 update rdoc
Watson1978 authored
654 * struct[symbol] = obj -> obj
655 * struct[fixnum] = obj -> obj
656 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
657 * Attribute Assignment---Assigns to the instance variable named by
658 * <i>symbol</i> or <i>fixnum</i> the value <i>obj</i> and
659 * returns it. Will raise a <code>NameError</code> if the named
660 * variable does not exist, or an <code>IndexError</code> if the index
661 * is out of range.
7bd034f @Watson1978 update rdoc
Watson1978 authored
662 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
663 * Customer = Struct.new(:name, :address, :zip)
664 * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
7bd034f @Watson1978 update rdoc
Watson1978 authored
665 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
666 * joe["name"] = "Luke"
667 * joe[:zip] = "90210"
7bd034f @Watson1978 update rdoc
Watson1978 authored
668 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
669 * joe.name #=> "Luke"
670 * joe.zip #=> "90210"
671 */
672
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
673 static VALUE
674 rb_struct_aset_imp(VALUE s, SEL sel, VALUE idx, VALUE val)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
675 {
676 long i;
677
678 if (TYPE(idx) == T_STRING || TYPE(idx) == T_SYMBOL) {
679 return rb_struct_aset_id(s, rb_to_id(idx), val);
680 }
681
682 i = NUM2LONG(idx);
683 if (i < 0) i = RSTRUCT_LEN(s) + i;
684 if (i < 0) {
685 rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
686 i, RSTRUCT_LEN(s));
687 }
688 if (RSTRUCT_LEN(s) <= i) {
689 rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
690 i, RSTRUCT_LEN(s));
691 }
692 rb_struct_modify(s);
a4117f9 adding missing write barriers
Laurent Sansonetti authored
693 GC_WB(&RSTRUCT_PTR(s)[i], val);
694 return val;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
695 }
696
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
697 VALUE
698 rb_struct_aset(VALUE s, VALUE idx, VALUE val)
699 {
700 return rb_struct_aset_imp(s, 0, idx, val);
701 }
702
9c1d230 committing experimental branch content
Laurent Sansonetti authored
703 static VALUE
704 struct_entry(VALUE s, long n)
705 {
706 return rb_struct_aref(s, LONG2NUM(n));
707 }
708
7bd034f @Watson1978 update rdoc
Watson1978 authored
709 /*
9c1d230 committing experimental branch content
Laurent Sansonetti authored
710 * call-seq:
7bd034f @Watson1978 update rdoc
Watson1978 authored
711 * struct.values_at(selector,... ) -> an_array
9c1d230 committing experimental branch content
Laurent Sansonetti authored
712 *
713 * Returns an array containing the elements in
7bd034f @Watson1978 update rdoc
Watson1978 authored
714 * +self+ corresponding to the given selector(s). The selectors
715 * may be either integer indices or ranges.
9c1d230 committing experimental branch content
Laurent Sansonetti authored
716 * See also </code>.select<code>.
7bd034f @Watson1978 update rdoc
Watson1978 authored
717 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
718 * a = %w{ a b c d e f }
719 * a.values_at(1, 3, 5)
720 * a.values_at(1, 3, 5, 7)
721 * a.values_at(-1, -3, -5, -7)
722 * a.values_at(1..3, 2...5)
723 */
724
725 static VALUE
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
726 rb_struct_values_at(VALUE s, SEL sel, int argc, VALUE *argv)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
727 {
728 return rb_get_values_at(s, RSTRUCT_LEN(s), argc, argv, struct_entry);
729 }
730
731 /*
732 * call-seq:
7bd034f @Watson1978 update rdoc
Watson1978 authored
733 * struct.select {|i| block } -> array
734 * struct.select -> an_enumerator
735 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
736 * Invokes the block passing in successive elements from
737 * <i>struct</i>, returning an array containing those elements
738 * for which the block returns a true value (equivalent to
739 * <code>Enumerable#select</code>).
7bd034f @Watson1978 update rdoc
Watson1978 authored
740 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
741 * Lots = Struct.new(:a, :b, :c, :d, :e, :f)
742 * l = Lots.new(11, 22, 33, 44, 55, 66)
743 * l.select {|v| (v % 2).zero? } #=> [22, 44, 66]
744 */
745
746 static VALUE
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
747 rb_struct_select(VALUE s, SEL sel, int argc, VALUE *argv)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
748 {
749 VALUE result;
750 long i;
751
752 if (argc > 0) {
753 rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
754 }
755 result = rb_ary_new();
756 for (i = 0; i < RSTRUCT_LEN(s); i++) {
757 VALUE v = rb_yield(RSTRUCT_PTR(s)[i]);
758 RETURN_IF_BROKEN();
759 if (RTEST(v)) {
760 rb_ary_push(result, RSTRUCT_PTR(s)[i]);
761 }
762 }
763
764 return result;
765 }
766
83c8c52 @Watson1978 move functions
Watson1978 authored
767 static VALUE
768 rb_struct_equal_r(VALUE s, VALUE s2, int recur)
769 {
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
770 VALUE *ptr, *ptr2;
771 long i, len;
772
83c8c52 @Watson1978 move functions
Watson1978 authored
773 if (recur) {
774 return Qtrue;
775 }
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
776 ptr = RSTRUCT_PTR(s);
777 ptr2 = RSTRUCT_PTR(s2);
778 len = RSTRUCT_LEN(s);
779 for (i=0; i<len; i++) {
780 if (!rb_equal(ptr[i], ptr2[i])) {
83c8c52 @Watson1978 move functions
Watson1978 authored
781 return Qfalse;
782 }
783 }
784 return Qtrue;
785 }
786
9c1d230 committing experimental branch content
Laurent Sansonetti authored
787 /*
788 * call-seq:
7bd034f @Watson1978 update rdoc
Watson1978 authored
789 * struct == other_struct -> true or false
790 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
791 * Equality---Returns <code>true</code> if <i>other_struct</i> is
792 * equal to this one: they must be of the same class as generated by
793 * <code>Struct::new</code>, and the values of all instance variables
794 * must be equal (according to <code>Object#==</code>).
7bd034f @Watson1978 update rdoc
Watson1978 authored
795 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
796 * Customer = Struct.new(:name, :address, :zip)
797 * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
798 * joejr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
799 * jane = Customer.new("Jane Doe", "456 Elm, Anytown NC", 12345)
800 * joe == joejr #=> true
801 * joe == jane #=> false
802 */
803
804 static VALUE
fb34693 support comparison of recursive structs
Laurent Sansonetti authored
805 rb_struct_equal(VALUE s, SEL sel, VALUE s2)
806 {
807 if (s == s2) {
808 return Qtrue;
809 }
810 if (TYPE(s2) != T_STRUCT) {
811 return Qfalse;
812 }
813 if (rb_obj_class(s) != rb_obj_class(s2)) {
814 return Qfalse;
815 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
816 if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
817 rb_bug("inconsistent struct"); /* should never happen */
818 }
fb34693 support comparison of recursive structs
Laurent Sansonetti authored
819 return rb_exec_recursive(rb_struct_equal_r, s, s2);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
820 }
821
822 static VALUE
3900c02 fix a bug in Struct#hash when called on recursive structs
Laurent Sansonetti authored
823 rb_struct_hash_r(VALUE s, VALUE s2, int recur)
824 {
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
825 long i, len;
826 st_index_t h;
827 VALUE n, *ptr;
828
506209e @Watson1978 use murmur hash
Watson1978 authored
829 h = rb_hash_start(rb_hash(rb_obj_class(s)));
3900c02 fix a bug in Struct#hash when called on recursive structs
Laurent Sansonetti authored
830 if (!recur) {
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
831 ptr = RSTRUCT_PTR(s);
832 len = RSTRUCT_LEN(s);
833 for (i = 0; i < len; i++) {
834 n = rb_hash(ptr[i]);
506209e @Watson1978 use murmur hash
Watson1978 authored
835 h = rb_hash_uint(h, NUM2LONG(n));
3900c02 fix a bug in Struct#hash when called on recursive structs
Laurent Sansonetti authored
836 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
837 }
506209e @Watson1978 use murmur hash
Watson1978 authored
838 h = rb_hash_end(h);
839 return INT2FIX(h);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
840 }
841
83c8c52 @Watson1978 move functions
Watson1978 authored
842 /*
843 * call-seq:
844 * struct.hash -> fixnum
845 *
846 * Return a hash value based on this struct's contents.
847 */
848
3900c02 fix a bug in Struct#hash when called on recursive structs
Laurent Sansonetti authored
849 static VALUE
850 rb_struct_hash(VALUE s, SEL sel)
851 {
6b3908b @Watson1978 use rb_exec_recursive_outer() instead of rb_exec_recursive() to retri…
Watson1978 authored
852 return rb_exec_recursive_outer(rb_struct_hash_r, s, 0);
3900c02 fix a bug in Struct#hash when called on recursive structs
Laurent Sansonetti authored
853 }
854
9c1d230 committing experimental branch content
Laurent Sansonetti authored
855 static VALUE
32f8948 fix Struct#eql? on nested structs
Laurent Sansonetti authored
856 rb_struct_eql_r(VALUE s, VALUE s2, int recur)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
857 {
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
858 VALUE *ptr, *ptr2;
859 long i, len;
860
32f8948 fix Struct#eql? on nested structs
Laurent Sansonetti authored
861 if (recur) {
862 return Qtrue;
863 }
d67475a @Watson1978 reducing macro calls inside of the loop by keeping pointers in local …
Watson1978 authored
864 ptr = RSTRUCT_PTR(s);
865 ptr2 = RSTRUCT_PTR(s2);
866 len = RSTRUCT_LEN(s);
867 for (i=0; i<len; i++) {
868 if (!rb_eql(ptr[i], ptr2[i])) {
32f8948 fix Struct#eql? on nested structs
Laurent Sansonetti authored
869 return Qfalse;
870 }
871 }
872 return Qtrue;
873 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
874
83c8c52 @Watson1978 move functions
Watson1978 authored
875 /*
876 * code-seq:
877 * struct.eql?(other) -> true or false
878 *
879 * Two structures are equal if they are the same object, or if all their
880 * fields are equal (using <code>eql?</code>).
881 */
882
32f8948 fix Struct#eql? on nested structs
Laurent Sansonetti authored
883 static VALUE
884 rb_struct_eql(VALUE s, SEL sel, VALUE s2)
885 {
886 if (s == s2) {
887 return Qtrue;
888 }
889 if (TYPE(s2) != T_STRUCT) {
890 return Qfalse;
891 }
892 if (rb_obj_class(s) != rb_obj_class(s2)) {
893 return Qfalse;
894 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
895 if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
896 rb_bug("inconsistent struct"); /* should never happen */
897 }
32f8948 fix Struct#eql? on nested structs
Laurent Sansonetti authored
898 return rb_exec_recursive(rb_struct_eql_r, s, s2);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
899 }
900
901 /*
902 * call-seq:
7bd034f @Watson1978 update rdoc
Watson1978 authored
903 * struct.length -> fixnum
904 * struct.size -> fixnum
905 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
906 * Returns the number of instance variables.
7bd034f @Watson1978 update rdoc
Watson1978 authored
907 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
908 * Customer = Struct.new(:name, :address, :zip)
909 * joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
910 * joe.length #=> 3
911 */
912
913 static VALUE
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
914 rb_struct_size(VALUE s, SEL sel)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
915 {
916 return LONG2FIX(RSTRUCT_LEN(s));
917 }
918
919 /*
920 * A <code>Struct</code> is a convenient way to bundle a number of
921 * attributes together, using accessor methods, without having to write
922 * an explicit class.
7bd034f @Watson1978 update rdoc
Watson1978 authored
923 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
924 * The <code>Struct</code> class is a generator of specific classes,
925 * each one of which is defined to hold a set of variables and their
926 * accessors. In these examples, we'll call the generated class
927 * ``<i>Customer</i>Class,'' and we'll show an example instance of that
928 * class as ``<i>Customer</i>Inst.''
7bd034f @Watson1978 update rdoc
Watson1978 authored
929 *
9c1d230 committing experimental branch content
Laurent Sansonetti authored
930 * In the descriptions that follow, the parameter <i>symbol</i> refers
931 * to a symbol, which is either a quoted string or a
932 * <code>Symbol</code> (such as <code>:name</code>).
933 */
934 void
935 Init_Struct(void)
936 {
937 rb_cStruct = rb_define_class("Struct", rb_cObject);
938 rb_include_module(rb_cStruct, rb_mEnumerable);
939
940 rb_undef_alloc_func(rb_cStruct);
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
941 rb_objc_define_method(*(VALUE *)rb_cStruct, "new", rb_struct_s_def, -1);
942
943 rb_objc_define_method(rb_cStruct, "initialize", rb_struct_initialize, -2);
944 rb_objc_define_method(rb_cStruct, "initialize_copy", rb_struct_init_copy, 1);
945
946 rb_objc_define_method(rb_cStruct, "==", rb_struct_equal, 1);
947 rb_objc_define_method(rb_cStruct, "eql?", rb_struct_eql, 1);
948 rb_objc_define_method(rb_cStruct, "hash", rb_struct_hash, 0);
949
950 rb_objc_define_method(rb_cStruct, "to_s", rb_struct_inspect, 0);
951 rb_objc_define_method(rb_cStruct, "inspect", rb_struct_inspect, 0);
952 rb_objc_define_method(rb_cStruct, "to_a", rb_struct_to_a, 0);
953 rb_objc_define_method(rb_cStruct, "values", rb_struct_to_a, 0);
954 rb_objc_define_method(rb_cStruct, "size", rb_struct_size, 0);
955 rb_objc_define_method(rb_cStruct, "length", rb_struct_size, 0);
956
957 rb_objc_define_method(rb_cStruct, "each", rb_struct_each, 0);
958 rb_objc_define_method(rb_cStruct, "each_pair", rb_struct_each_pair, 0);
4d321d1 fixed several bugs in the Struct class, now it's usable again
Laurent Sansonetti authored
959 rb_objc_define_method(rb_cStruct, "[]", rb_struct_aref_imp, 1);
960 rb_objc_define_method(rb_cStruct, "[]=", rb_struct_aset_imp, 2);
dc1f047 ported to rb_objc_define_method()
Laurent Sansonetti authored
961 rb_objc_define_method(rb_cStruct, "select", rb_struct_select, -1);
962 rb_objc_define_method(rb_cStruct, "values_at", rb_struct_values_at, -1);
963
964 rb_objc_define_method(rb_cStruct, "members", rb_struct_members_m, 0);
b2b73dd @Watson1978 cache symbol to reduce calls to rb_intern()
Watson1978 authored
965 id_members = rb_intern("__members__");
9c1d230 committing experimental branch content
Laurent Sansonetti authored
966 }
Something went wrong with that request. Please try again.