Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 895 lines (803 sloc) 21.645 kb
9c1d230 committing experimental branch content
Laurent Sansonetti authored
1 /* -*-c-*- */
2 /*
3 * This file is included by vm_eval.c
4 */
5
6 static ID __send__, object_id;
7 static ID removed, singleton_removed, undefined, singleton_undefined;
8 static ID eqq, each, aref, aset, match, missing;
9 static ID added, singleton_added;
10
11 void
12 rb_add_method(VALUE klass, ID mid, NODE * node, int noex)
13 {
14 // TODO
15 return;
16 }
17
18 void
19 rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE))
20 {
21 // TODO
22 #if 0
23 Check_Type(klass, T_CLASS);
24 rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, NEW_CFUNC(func, 0),
25 NOEX_PUBLIC);
26 #endif
27 }
28
29 void
30 rb_undef_alloc_func(VALUE klass)
31 {
32 // TODO
33 #if 0
34 Check_Type(klass, T_CLASS);
35 rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, 0, NOEX_UNDEF);
36 #endif
37 }
38
39 rb_alloc_func_t
40 rb_get_alloc_func(VALUE klass)
41 {
42 NODE *n;
43 Check_Type(klass, T_CLASS);
44 n = rb_method_node(CLASS_OF(klass), ID_ALLOCATOR);
45 if (!n) return 0;
46 if (nd_type(n) != NODE_METHOD) return 0;
47 n = n->nd_body;
48 if (nd_type(n) != NODE_CFUNC) return 0;
49 return (rb_alloc_func_t)n->nd_cfnc;
50 }
51
52 static NODE *
53 search_method(VALUE klass, ID id, VALUE *klassp)
54 {
55 NODE *node;
56 if (klass == 0) {
57 return NULL;
58 }
59 node = rb_method_node(klass, id);
60 if (node != NULL) {
61 if (klassp != NULL) { /* TODO honour klassp */
62 *klassp = klass;
63 }
64 }
65 return node;
66 }
67
68 /*
69 * search method body (NODE_METHOD)
70 * with : klass and id
71 * without : method cache
72 *
73 * if you need method node with method cache, use
74 * rb_method_node()
75 */
76 NODE *
77 rb_get_method_body(VALUE klass, ID id, ID *idp)
78 {
79 return search_method(klass, id, NULL);
80 }
81
82 NODE *
83 rb_method_node(VALUE klass, ID id)
84 {
3c2c617 disable rb_method_node() for now because it's wrongly implemented
Laurent Sansonetti authored
85 return NULL;
86 #if 0 // TODO
9c1d230 committing experimental branch content
Laurent Sansonetti authored
87 NODE *node = rb_objc_method_node(klass, id, NULL, NULL);
88 if (node == NULL && id != ID_ALLOCATOR) {
89 const char *id_str = rb_id2name(id);
90 size_t slen = strlen(id_str);
91
92 if (strcmp(id_str, "retain") == 0
93 || strcmp(id_str, "release") == 0
94 || strcmp(id_str, "zone") == 0) {
95 char buf[100];
96 snprintf(buf, sizeof buf, "__rb_%s__", id_str);
97 return rb_method_node(klass, rb_intern(buf));
98 }
99 else {
100 if (id_str[slen - 1] == ':') {
101 return NULL;
102 }
103 else {
104 char buf[100];
105 snprintf(buf, sizeof buf, "%s:", id_str);
106 return rb_method_node(klass, rb_intern(buf));
107 }
108 }
109 }
110 return node;
3c2c617 disable rb_method_node() for now because it's wrongly implemented
Laurent Sansonetti authored
111 #endif
9c1d230 committing experimental branch content
Laurent Sansonetti authored
112 }
113
114 static void
115 remove_method(VALUE klass, ID mid)
116 {
117 if (klass == rb_cObject) {
118 rb_secure(4);
119 }
120 if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
121 rb_raise(rb_eSecurityError, "Insecure: can't remove method");
122 }
123 if (OBJ_FROZEN(klass))
124 rb_error_frozen("class/module");
125 if (mid == object_id || mid == __send__ || mid == idInitialize) {
126 rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
127 }
128 SEL sel;
129 Method m;
130
131 sel = sel_registerName(rb_id2name(mid));
132 m = class_getInstanceMethod((Class)klass, sel);
133 if (m == NULL) {
134 char buf[100];
135 size_t len = strlen((char *)sel);
136 if (((char *)sel)[len - 1] != ':') {
137 snprintf(buf, sizeof buf, "%s:", (char *)sel);
138 sel = sel_registerName(buf);
139 m = class_getInstanceMethod((Class)klass, sel);
140 }
141 }
142 if (m == NULL) {
143 rb_name_error(mid, "method `%s' not defined in %s",
144 rb_id2name(mid), rb_class2name(klass));
145 }
637ca0f removing extra fat out of objc.m
Laurent Sansonetti authored
146 if (rb_vm_get_method_node(method_getImplementation(m)) == NULL) {
69ef419 added AOT compilation support for method definitions and constants
Laurent Sansonetti authored
147 rb_warn("removing pure Objective-C method `%s' may cause serious " \
148 "problem", rb_id2name(mid));
9c1d230 committing experimental branch content
Laurent Sansonetti authored
149 }
150 method_setImplementation(m, NULL);
151
152 if (RCLASS_SINGLETON(klass)) {
153 rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1,
154 ID2SYM(mid));
155 }
156 else {
157 rb_funcall(klass, removed, 1, ID2SYM(mid));
158 }
159 }
160
161 void
162 rb_remove_method(VALUE klass, const char *name)
163 {
164 remove_method(klass, rb_intern(name));
165 }
166
167 /*
168 * call-seq:
169 * remove_method(symbol) => self
170 *
171 * Removes the method identified by _symbol_ from the current
172 * class. For an example, see <code>Module.undef_method</code>.
173 */
174
175 static VALUE
176 rb_mod_remove_method(VALUE mod, SEL sel, int argc, VALUE *argv)
177 {
178 int i;
179
180 for (i = 0; i < argc; i++) {
181 remove_method(mod, rb_to_id(argv[i]));
182 }
183 return mod;
184 }
185
186 #undef rb_disable_super
187 #undef rb_enable_super
188
189 void
190 rb_disable_super(VALUE klass, const char *name)
191 {
192 /* obsolete - no use */
193 }
194
195 void
196 rb_enable_super(VALUE klass, const char *name)
197 {
198 rb_warning("rb_enable_super() is obsolete");
199 }
200
201 void rb_print_undef(VALUE, ID, int);
202
203 static void
204 rb_export_method(VALUE klass, ID name, ID noex)
205 {
69ef419 added AOT compilation support for method definitions and constants
Laurent Sansonetti authored
206 rb_vm_method_node_t *node;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
207 SEL sel;
208
209 if (klass == rb_cObject) {
210 rb_secure(4);
211 }
212
213 if (!rb_vm_lookup_method2((Class)klass, name, &sel, NULL, &node)) {
214 if (TYPE(klass) != T_MODULE
215 || !rb_vm_lookup_method2((Class)rb_cObject, name, &sel, NULL, &node)) {
216 rb_print_undef(klass, name, 0);
217 }
218 }
219
220 #if 0 // TODO
221 if (node->nd_noex != noex) {
222 // TODO if the method exists on a super class, we should add a new method
223 // with the correct noex that calls super
224 assert(!rb_vm_lookup_method((Class)RCLASS_SUPER(klass), sel, NULL, NULL));
225
226 node->nd_noex = noex;
227 }
228 #endif
229 }
230
231 int
232 rb_method_boundp(VALUE klass, ID id, int ex)
233 {
234 NODE *method;
235
236 if ((method = rb_method_node(klass, id)) != 0) {
237 if (ex && (method->nd_noex & NOEX_PRIVATE)) {
238 return Qfalse;
239 }
240 return Qtrue;
241 }
242 return Qfalse;
243 }
244
245 void
246 rb_attr(VALUE klass, ID id, int read, int write, int ex)
247 {
248 const char *name;
249 int noex;
250
251 if (!ex) {
252 noex = NOEX_PUBLIC;
253 }
254 else {
255 // TODO honor current scope ex
256 noex = NOEX_PUBLIC;
257 }
258
259 if (!rb_is_local_id(id) && !rb_is_const_id(id)) {
260 rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id));
261 }
262 name = rb_id2name(id);
263 if (!name) {
264 rb_raise(rb_eArgError, "argument needs to be symbol or string");
265 }
266 rb_vm_define_attr((Class)klass, name, read, write, noex);
267 if (write) {
268 rb_objc_define_kvo_setter(klass, id);
269 }
270 }
271
272 void
273 rb_undef(VALUE klass, ID id)
274 {
275 // TODO
276 #if 0
277 VALUE origin;
278 NODE *body;
279
280 #if 0 // TODO
281 if (rb_vm_cbase() == rb_cObject && klass == rb_cObject) {
282 rb_secure(4);
283 }
284 #endif
285 if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
286 rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'",
287 rb_id2name(id));
288 }
289 rb_frozen_class_p(klass);
290 if (id == object_id || id == __send__ || id == idInitialize) {
291 rb_warn("undefining `%s' may cause serious problem", rb_id2name(id));
292 }
293 /* TODO: warn if a very important method of NSObject is undefined
294 * by default, pure objc methods are not exposed by introspections API
295 */
296 body = search_method(klass, id, &origin);
297 if (!body || !body->nd_body) {
298 const char *s0 = " class";
299 VALUE c = klass;
300
301 if (RCLASS_SINGLETON(c)) {
302 VALUE obj = rb_iv_get(klass, "__attached__");
303
304 switch (TYPE(obj)) {
305 case T_MODULE:
306 case T_CLASS:
307 c = obj;
308 s0 = "";
309 }
310 }
311 else if (TYPE(c) == T_MODULE) {
312 s0 = " module";
313 }
314 rb_name_error(id, "undefined method `%s' for%s `%s'",
315 rb_id2name(id), s0, rb_class2name(c));
316 }
317
318 rb_add_method(klass, id, 0, NOEX_PUBLIC);
319
320 if (RCLASS_SINGLETON(klass)) {
321 rb_funcall(rb_iv_get(klass, "__attached__"),
322 singleton_undefined, 1, ID2SYM(id));
323 }
324 else {
325 rb_funcall(klass, undefined, 1, ID2SYM(id));
326 }
327 #endif
328 }
329
330 /*
331 * call-seq:
332 * undef_method(symbol) => self
333 *
334 * Prevents the current class from responding to calls to the named
335 * method. Contrast this with <code>remove_method</code>, which deletes
336 * the method from the particular class; Ruby will still search
337 * superclasses and mixed-in modules for a possible receiver.
338 *
339 * class Parent
340 * def hello
341 * puts "In parent"
342 * end
343 * end
344 * class Child < Parent
345 * def hello
346 * puts "In child"
347 * end
348 * end
349 *
350 *
351 * c = Child.new
352 * c.hello
353 *
354 *
355 * class Child
356 * remove_method :hello # remove from child, still in parent
357 * end
358 * c.hello
359 *
360 *
361 * class Child
362 * undef_method :hello # prevent any calls to 'hello'
363 * end
364 * c.hello
365 *
366 * <em>produces:</em>
367 *
368 * In child
369 * In parent
370 * prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
371 */
372
373 static VALUE
374 rb_mod_undef_method(VALUE mod, SEL sel, int argc, VALUE *argv)
375 {
376 int i;
377 for (i = 0; i < argc; i++) {
378 rb_undef(mod, rb_to_id(argv[i]));
379 }
380 return mod;
381 }
382
383 /*
384 * call-seq:
385 * mod.method_defined?(symbol) => true or false
386 *
387 * Returns +true+ if the named method is defined by
388 * _mod_ (or its included modules and, if _mod_ is a class,
389 * its ancestors). Public and protected methods are matched.
390 *
391 * module A
392 * def method1() end
393 * end
394 * class B
395 * def method2() end
396 * end
397 * class C < B
398 * include A
399 * def method3() end
400 * end
401 *
402 * A.method_defined? :method1 #=> true
403 * C.method_defined? "method1" #=> true
404 * C.method_defined? "method2" #=> true
405 * C.method_defined? "method3" #=> true
406 * C.method_defined? "method4" #=> false
407 */
408
409 static VALUE
410 rb_mod_method_defined(VALUE mod, SEL sel, VALUE mid)
411 {
412 return rb_method_boundp(mod, rb_to_id(mid), 1);
413 }
414
415 #define VISI_CHECK(x,f) (((x)&NOEX_MASK) == (f))
416
417 /*
418 * call-seq:
419 * mod.public_method_defined?(symbol) => true or false
420 *
421 * Returns +true+ if the named public method is defined by
422 * _mod_ (or its included modules and, if _mod_ is a class,
423 * its ancestors).
424 *
425 * module A
426 * def method1() end
427 * end
428 * class B
429 * protected
430 * def method2() end
431 * end
432 * class C < B
433 * include A
434 * def method3() end
435 * end
436 *
437 * A.method_defined? :method1 #=> true
438 * C.public_method_defined? "method1" #=> true
439 * C.public_method_defined? "method2" #=> false
440 * C.method_defined? "method2" #=> true
441 */
442
443 static VALUE
444 rb_mod_public_method_defined(VALUE mod, SEL sel, VALUE mid)
445 {
446 ID id = rb_to_id(mid);
447 NODE *method;
448
449 method = rb_method_node(mod, id);
450 if (method) {
451 if (VISI_CHECK(method->nd_noex, NOEX_PUBLIC))
452 return Qtrue;
453 }
454 return Qfalse;
455 }
456
457 /*
458 * call-seq:
459 * mod.private_method_defined?(symbol) => true or false
460 *
461 * Returns +true+ if the named private method is defined by
462 * _ mod_ (or its included modules and, if _mod_ is a class,
463 * its ancestors).
464 *
465 * module A
466 * def method1() end
467 * end
468 * class B
469 * private
470 * def method2() end
471 * end
472 * class C < B
473 * include A
474 * def method3() end
475 * end
476 *
477 * A.method_defined? :method1 #=> true
478 * C.private_method_defined? "method1" #=> false
479 * C.private_method_defined? "method2" #=> true
480 * C.method_defined? "method2" #=> false
481 */
482
483 static VALUE
484 rb_mod_private_method_defined(VALUE mod, SEL sel, VALUE mid)
485 {
486 ID id = rb_to_id(mid);
487 NODE *method;
488
489 method = rb_method_node(mod, id);
490 if (method) {
491 if (VISI_CHECK(method->nd_noex, NOEX_PRIVATE))
492 return Qtrue;
493 }
494 return Qfalse;
495 }
496
497 /*
498 * call-seq:
499 * mod.protected_method_defined?(symbol) => true or false
500 *
501 * Returns +true+ if the named protected method is defined
502 * by _mod_ (or its included modules and, if _mod_ is a
503 * class, its ancestors).
504 *
505 * module A
506 * def method1() end
507 * end
508 * class B
509 * protected
510 * def method2() end
511 * end
512 * class C < B
513 * include A
514 * def method3() end
515 * end
516 *
517 * A.method_defined? :method1 #=> true
518 * C.protected_method_defined? "method1" #=> false
519 * C.protected_method_defined? "method2" #=> true
520 * C.method_defined? "method2" #=> true
521 */
522
523 static VALUE
524 rb_mod_protected_method_defined(VALUE mod, SEL sel, VALUE mid)
525 {
526 ID id = rb_to_id(mid);
527 NODE *method;
528
529 method = rb_method_node(mod, id);
530 if (method) {
531 if (VISI_CHECK(method->nd_noex, NOEX_PROTECTED))
532 return Qtrue;
533 }
534 return Qfalse;
535 }
536
537 void
538 rb_alias(VALUE klass, ID name, ID def)
539 {
540 rb_vm_alias(klass, name, def);
541 }
542
543 /*
544 * call-seq:
545 * alias_method(new_name, old_name) => self
546 *
547 * Makes <i>new_name</i> a new copy of the method <i>old_name</i>. This can
548 * be used to retain access to methods that are overridden.
549 *
550 * module Mod
551 * alias_method :orig_exit, :exit
552 * def exit(code=0)
553 * puts "Exiting with code #{code}"
554 * orig_exit(code)
555 * end
556 * end
557 * include Mod
558 * exit(99)
559 *
560 * <em>produces:</em>
561 *
562 * Exiting with code 99
563 */
564
565 static VALUE
566 rb_mod_alias_method(VALUE mod, SEL sel, VALUE newname, VALUE oldname)
567 {
568 rb_alias(mod, rb_to_id(newname), rb_to_id(oldname));
569 return mod;
570 }
571
572 static void
573 secure_visibility(VALUE self)
574 {
575 if (rb_safe_level() >= 4 && !OBJ_TAINTED(self)) {
576 rb_raise(rb_eSecurityError,
577 "Insecure: can't change method visibility");
578 }
579 }
580
581 static void
582 set_method_visibility(VALUE self, int argc, VALUE *argv, ID ex)
583 {
584 int i;
585 secure_visibility(self);
586 for (i = 0; i < argc; i++) {
587 rb_export_method(self, rb_to_id(argv[i]), ex);
588 }
589 }
590
591 /*
592 * call-seq:
593 * public => self
594 * public(symbol, ...) => self
595 *
596 * With no arguments, sets the default visibility for subsequently
597 * defined methods to public. With arguments, sets the named methods to
598 * have public visibility.
599 */
600
601 static VALUE
602 rb_mod_public(VALUE module, SEL sel, int argc, VALUE *argv)
603 {
604 secure_visibility(module);
605 if (argc == 0) {
606 // TODO change scope!
607 }
608 else {
609 set_method_visibility(module, argc, argv, NOEX_PUBLIC);
610 }
611 return module;
612 }
613
614 /*
615 * call-seq:
616 * protected => self
617 * protected(symbol, ...) => self
618 *
619 * With no arguments, sets the default visibility for subsequently
620 * defined methods to protected. With arguments, sets the named methods
621 * to have protected visibility.
622 */
623
624 static VALUE
625 rb_mod_protected(VALUE module, SEL sel, int argc, VALUE *argv)
626 {
627 secure_visibility(module);
628 if (argc == 0) {
629 // TODO change scope!
630 }
631 else {
632 set_method_visibility(module, argc, argv, NOEX_PROTECTED);
633 }
634 return module;
635 }
636
637 /*
638 * call-seq:
639 * private => self
640 * private(symbol, ...) => self
641 *
642 * With no arguments, sets the default visibility for subsequently
643 * defined methods to private. With arguments, sets the named methods
644 * to have private visibility.
645 *
646 * module Mod
647 * def a() end
648 * def b() end
649 * private
650 * def c() end
651 * private :a
652 * end
653 * Mod.private_instance_methods #=> [:a, :c]
654 */
655
656 static VALUE
657 rb_mod_private(VALUE module, SEL sel, int argc, VALUE *argv)
658 {
659 secure_visibility(module);
660 if (argc == 0) {
661 // TODO change scope!
662 }
663 else {
664 set_method_visibility(module, argc, argv, NOEX_PRIVATE);
665 }
666 return module;
667 }
668
669 /*
670 * call-seq:
671 * mod.public_class_method(symbol, ...) => mod
672 *
673 * Makes a list of existing class methods public.
674 */
675
676 static VALUE
677 rb_mod_public_method(VALUE obj, SEL sel, int argc, VALUE *argv)
678 {
679 set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PUBLIC);
680 return obj;
681 }
682
683 /*
684 * call-seq:
685 * mod.private_class_method(symbol, ...) => mod
686 *
687 * Makes existing class methods private. Often used to hide the default
688 * constructor <code>new</code>.
689 *
690 * class SimpleSingleton # Not thread safe
691 * private_class_method :new
692 * def SimpleSingleton.create(*args, &block)
693 * @me = new(*args, &block) if ! @me
694 * @me
695 * end
696 * end
697 */
698
699 static VALUE
700 rb_mod_private_method(VALUE obj, SEL sel, int argc, VALUE *argv)
701 {
702 set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PRIVATE);
703 return obj;
704 }
705
706 /*
707 * call-seq:
708 * public
709 * public(symbol, ...)
710 *
711 * With no arguments, sets the default visibility for subsequently
712 * defined methods to public. With arguments, sets the named methods to
713 * have public visibility.
714 */
715
716 static VALUE
717 top_public(VALUE recv, SEL sel, int argc, VALUE *argv)
718 {
719 return rb_mod_public(rb_cObject, 0, argc, argv);
720 }
721
722 static VALUE
723 top_private(VALUE recv, SEL sel, int argc, VALUE *argv)
724 {
725 return rb_mod_private(rb_cObject, 0, argc, argv);
726 }
727
728 /*
729 * call-seq:
730 * module_function(symbol, ...) => self
731 *
732 * Creates module functions for the named methods. These functions may
733 * be called with the module as a receiver, and also become available
734 * as instance methods to classes that mix in the module. Module
735 * functions are copies of the original, and so may be changed
736 * independently. The instance-method versions are made private. If
737 * used with no arguments, subsequently defined methods become module
738 * functions.
739 *
740 * module Mod
741 * def one
742 * "This is one"
743 * end
744 * module_function :one
745 * end
746 * class Cls
747 * include Mod
748 * def callOne
749 * one
750 * end
751 * end
752 * Mod.one #=> "This is one"
753 * c = Cls.new
754 * c.callOne #=> "This is one"
755 * module Mod
756 * def one
757 * "This is the new one"
758 * end
759 * end
760 * Mod.one #=> "This is one"
761 * c.callOne #=> "This is the new one"
762 */
763
764 static VALUE
765 rb_mod_modfunc(VALUE module, SEL sel, int argc, VALUE *argv)
766 {
767 int i;
768
769 if (TYPE(module) != T_MODULE) {
770 rb_raise(rb_eTypeError, "module_function must be called for modules");
771 }
772
773 secure_visibility(module);
774 if (argc == 0) {
775 // TODO change scope!
776 return module;
777 }
778
779 set_method_visibility(module, argc, argv, NOEX_PRIVATE);
780
781 for (i = 0; i < argc; i++) {
782 ID id = rb_to_id(argv[i]);
783 IMP imp;
69ef419 added AOT compilation support for method definitions and constants
Laurent Sansonetti authored
784 rb_vm_method_node_t *node;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
785 SEL sel;
786
787 if (!rb_vm_lookup_method2((Class)module, id, &sel, &imp, &node)) {
788 // Methods are checked in set_method_visibility().
789 rb_bug("undefined method `%s'; can't happen", rb_id2name(id));
790 }
791
a6e43f0 fix a few regressions
Laurent Sansonetti authored
792 rb_vm_define_method2(*(Class *)module, sel, node, false);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
793 }
794
795 return module;
796 }
797
798 /*
799 * call-seq:
800 * obj.respond_to?(symbol, include_private=false) => true or false
801 *
802 * Returns +true+> if _obj_ responds to the given
803 * method. Private methods are included in the search only if the
804 * optional second parameter evaluates to +true+.
805 */
806
807 //static NODE *basic_respond_to = 0;
808
809 int
810 rb_obj_respond_to(VALUE obj, ID id, int priv)
811 {
812 const char *id_name = rb_id2name(id);
813 SEL sel = sel_registerName(id_name);
814 if (!rb_vm_respond_to(obj, sel, priv)) {
815 char buf[100];
816 snprintf(buf, sizeof buf, "%s:", id_name);
817 sel = sel_registerName(buf);
928f4e8 work in progress on the new c/objc dispatcher
Laurent Sansonetti authored
818 return rb_vm_respond_to(obj, sel, priv) == true ? 1 : 0;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
819 }
820 return 1;
821 }
822
823 int
824 rb_respond_to(VALUE obj, ID id)
825 {
826 return rb_obj_respond_to(obj, id, Qfalse);
827 }
828
829 /*
830 * call-seq:
831 * obj.respond_to?(symbol, include_private=false) => true or false
832 *
833 * Returns +true+> if _obj_ responds to the given
834 * method. Private methods are included in the search only if the
835 * optional second parameter evaluates to +true+.
836 */
837
838 static VALUE
839 obj_respond_to(VALUE obj, SEL sel, int argc, VALUE *argv)
840 {
841 VALUE mid, priv;
842 ID id;
843
844 rb_scan_args(argc, argv, "11", &mid, &priv);
845 id = rb_to_id(mid);
846 return rb_obj_respond_to(obj, id, RTEST(priv)) ? Qtrue : Qfalse;
847 return Qfalse;
848 }
849
850 IMP basic_respond_to_imp = NULL;
851
852 void
853 Init_eval_method(void)
854 {
855 rb_objc_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
856 basic_respond_to_imp = class_getMethodImplementation((Class)rb_mKernel, selRespondTo);
857 //basic_respond_to = rb_method_node(rb_cObject, idRespond_to);
858 //rb_register_mark_object((VALUE)basic_respond_to);
859
860 rb_objc_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
861 rb_objc_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
862 rb_objc_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
863 rb_objc_define_private_method(rb_cModule, "public", rb_mod_public, -1);
864 rb_objc_define_private_method(rb_cModule, "protected", rb_mod_protected, -1);
865 rb_objc_define_private_method(rb_cModule, "private", rb_mod_private, -1);
866 rb_objc_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
867
868 rb_objc_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
869 rb_objc_define_method(rb_cModule, "public_method_defined?", rb_mod_public_method_defined, 1);
870 rb_objc_define_method(rb_cModule, "private_method_defined?", rb_mod_private_method_defined, 1);
871 rb_objc_define_method(rb_cModule, "protected_method_defined?", rb_mod_protected_method_defined, 1);
872 rb_objc_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
873 rb_objc_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
874
875 VALUE cTopLevel = *(VALUE *)rb_vm_top_self();
876 rb_objc_define_method(cTopLevel, "public", top_public, -1);
877 rb_objc_define_method(cTopLevel, "private", top_private, -1);
878
879 object_id = rb_intern("object_id");
880 __send__ = rb_intern("__send__");
881 eqq = rb_intern("===");
882 each = rb_intern("each");
883 aref = rb_intern("[]");
884 aset = rb_intern("[]=");
885 match = rb_intern("=~");
886 missing = rb_intern("method_missing");
887 added = rb_intern("method_added");
888 singleton_added = rb_intern("singleton_method_added");
889 removed = rb_intern("method_removed");
890 singleton_removed = rb_intern("singleton_method_removed");
891 undefined = rb_intern("method_undefined");
892 singleton_undefined = rb_intern("singleton_method_undefined");
893 }
894
Something went wrong with that request. Please try again.