Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 748 lines (671 sloc) 18.904 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 static void
12 remove_method(VALUE klass, ID mid)
13 {
14 if (klass == rb_cObject) {
15 rb_secure(4);
16 }
3e5975d @Watson1978 Module#remove_method with untrusted will not throw a SecurityError.
Watson1978 authored
17 if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(klass)) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
18 rb_raise(rb_eSecurityError, "Insecure: can't remove method");
19 }
e732379 moved the removed_method code to the VM + fixed undef_method callbacks
Laurent Sansonetti authored
20 if (OBJ_FROZEN(klass)) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
21 rb_error_frozen("class/module");
e732379 moved the removed_method code to the VM + fixed undef_method callbacks
Laurent Sansonetti authored
22 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
23 if (mid == object_id || mid == __send__ || mid == idInitialize) {
24 rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
25 }
26
e732379 moved the removed_method code to the VM + fixed undef_method callbacks
Laurent Sansonetti authored
27 rb_vm_remove_method((Class)klass, mid);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
28 }
29
30 void
31 rb_remove_method(VALUE klass, const char *name)
32 {
33 remove_method(klass, rb_intern(name));
34 }
35
36 /*
37 * call-seq:
38 * remove_method(symbol) => self
39 *
40 * Removes the method identified by _symbol_ from the current
41 * class. For an example, see <code>Module.undef_method</code>.
42 */
43
44 static VALUE
45 rb_mod_remove_method(VALUE mod, SEL sel, int argc, VALUE *argv)
46 {
e732379 moved the removed_method code to the VM + fixed undef_method callbacks
Laurent Sansonetti authored
47 for (int i = 0; i < argc; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
48 remove_method(mod, rb_to_id(argv[i]));
49 }
50 return mod;
51 }
52
53 #undef rb_disable_super
54 #undef rb_enable_super
55
56 void
57 rb_disable_super(VALUE klass, const char *name)
58 {
59 /* obsolete - no use */
60 }
61
62 void
63 rb_enable_super(VALUE klass, const char *name)
64 {
65 rb_warning("rb_enable_super() is obsolete");
66 }
67
68 void rb_print_undef(VALUE, ID, int);
69
70 static void
71 rb_export_method(VALUE klass, ID name, ID noex)
72 {
69ef419 added AOT compilation support for method definitions and constants
Laurent Sansonetti authored
73 rb_vm_method_node_t *node;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
74 SEL sel;
75
76 if (klass == rb_cObject) {
77 rb_secure(4);
78 }
79
80 if (!rb_vm_lookup_method2((Class)klass, name, &sel, NULL, &node)) {
81 if (TYPE(klass) != T_MODULE
82 || !rb_vm_lookup_method2((Class)rb_cObject, name, &sel, NULL, &node)) {
83 rb_print_undef(klass, name, 0);
84 }
85 }
86
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
87 if (node == NULL) {
88 rb_raise(rb_eRuntimeError,
89 "can't change visibility of non Ruby method `%s'",
90 sel_getName(sel));
91 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
92
6aab6c5 fix a bug when changing a method's visibility to public would not be tak...
Laurent Sansonetti authored
93 long flags = (node->flags & ~VM_METHOD_PRIVATE) & ~VM_METHOD_PROTECTED;
846054c when changing the visibility of a method that is included in classes, ma...
Laurent Sansonetti authored
94 switch (noex) {
95 case NOEX_PRIVATE:
96 flags |= VM_METHOD_PRIVATE;
97 break;
98
99 case NOEX_PROTECTED:
100 flags |= VM_METHOD_PROTECTED;
101 break;
102
103 default:
104 break;
105 }
106
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
107 VALUE sklass = RCLASS_SUPER(klass);
108 if (sklass != 0) {
d3eea39 when changing the visibility of a method and duplicating its entry in th...
Laurent Sansonetti authored
109 IMP imp;
110 rb_vm_method_node_t *snode;
111 if (rb_vm_lookup_method((Class)sklass, sel, &imp, &snode)
112 && imp == node->objc_imp) {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
113 // The method actually exists on a superclass, we need to duplicate
d3eea39 when changing the visibility of a method and duplicating its entry in th...
Laurent Sansonetti authored
114 // it to the current class, keeping the same flags.
115 if (snode != NULL) {
116 if (snode->flags & VM_METHOD_EMPTY) {
117 flags |= VM_METHOD_EMPTY;
118 }
119 if (snode->flags & VM_METHOD_FBODY) {
120 flags |= VM_METHOD_FBODY;
121 }
122 }
846054c when changing the visibility of a method that is included in classes, ma...
Laurent Sansonetti authored
123 rb_vm_define_method2((Class)klass, sel, node, flags, false);
124 return;
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
125 }
126 }
127
6aab6c5 fix a bug when changing a method's visibility to public would not be tak...
Laurent Sansonetti authored
128 node->flags = flags;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
129 }
130
131 void
132 rb_attr(VALUE klass, ID id, int read, int write, int ex)
133 {
134 if (!rb_is_local_id(id) && !rb_is_const_id(id)) {
135 rb_name_error(id, "invalid attribute name `%s'", rb_id2name(id));
136 }
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
137 const char *name = rb_id2name(id);
138 if (name == NULL) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
139 rb_raise(rb_eArgError, "argument needs to be symbol or string");
140 }
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
141 rb_vm_define_attr((Class)klass, name, read, write);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
142 if (write) {
143 rb_objc_define_kvo_setter(klass, id);
144 }
145 }
146
147 void
148 rb_undef(VALUE klass, ID id)
149 {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
150 if (klass == rb_cObject) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
151 rb_secure(4);
152 }
2a7e2e5 @Watson1978 Module#undef_method with untrusted will not throw a SecurityError.
Watson1978 authored
153 if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(klass)) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
154 rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'",
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
155 rb_id2name(id));
9c1d230 committing experimental branch content
Laurent Sansonetti authored
156 }
157 rb_frozen_class_p(klass);
158 if (id == object_id || id == __send__ || id == idInitialize) {
159 rb_warn("undefining `%s' may cause serious problem", rb_id2name(id));
160 }
161
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
162 rb_vm_undef_method((Class)klass, id, true);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
163 }
164
165 /*
166 * call-seq:
167 * undef_method(symbol) => self
168 *
169 * Prevents the current class from responding to calls to the named
170 * method. Contrast this with <code>remove_method</code>, which deletes
171 * the method from the particular class; Ruby will still search
172 * superclasses and mixed-in modules for a possible receiver.
173 *
174 * class Parent
175 * def hello
176 * puts "In parent"
177 * end
178 * end
179 * class Child < Parent
180 * def hello
181 * puts "In child"
182 * end
183 * end
184 *
185 *
186 * c = Child.new
187 * c.hello
188 *
189 *
190 * class Child
191 * remove_method :hello # remove from child, still in parent
192 * end
193 * c.hello
194 *
195 *
196 * class Child
197 * undef_method :hello # prevent any calls to 'hello'
198 * end
199 * c.hello
200 *
201 * <em>produces:</em>
202 *
203 * In child
204 * In parent
205 * prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
206 */
207
208 static VALUE
209 rb_mod_undef_method(VALUE mod, SEL sel, int argc, VALUE *argv)
210 {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
211 for (int i = 0; i < argc; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
212 rb_undef(mod, rb_to_id(argv[i]));
213 }
214 return mod;
215 }
216
217 /*
218 * call-seq:
219 * mod.method_defined?(symbol) => true or false
220 *
221 * Returns +true+ if the named method is defined by
222 * _mod_ (or its included modules and, if _mod_ is a class,
223 * its ancestors). Public and protected methods are matched.
224 *
225 * module A
226 * def method1() end
227 * end
228 * class B
229 * def method2() end
230 * end
231 * class C < B
232 * include A
233 * def method3() end
234 * end
235 *
236 * A.method_defined? :method1 #=> true
237 * C.method_defined? "method1" #=> true
238 * C.method_defined? "method2" #=> true
239 * C.method_defined? "method3" #=> true
240 * C.method_defined? "method4" #=> false
241 */
242
59fba25 Kernel#respond_to_missing?: added
Laurent Sansonetti authored
243 static SEL selRespondToDefault = 0;
244
9e76215 fixed Module#method_defined?
Laurent Sansonetti authored
245 static bool
468a2ea Move Obj-C related headers around.
Thibault Martin-Lagardette authored
246 rb_obj_respond_to2(VALUE obj, VALUE klass, ID id, int priv, int check_override)
9e76215 fixed Module#method_defined?
Laurent Sansonetti authored
247 {
248 const char *id_name = rb_id2name(id);
249 SEL sel = sel_registerName(id_name);
250 if (!rb_vm_respond_to2(obj, klass, sel, priv, check_override)) {
251 char buf[100];
252 snprintf(buf, sizeof buf, "%s:", id_name);
253 sel = sel_registerName(buf);
59fba25 Kernel#respond_to_missing?: added
Laurent Sansonetti authored
254 if (!rb_vm_respond_to2(obj, klass, sel, priv, check_override)) {
255 VALUE args[2];
256 args[0] = ID2SYM(id);
257 args[1] = priv ? Qtrue : Qfalse;
70ea0b5 per-vm method cache + misc fixes/improvements
Laurent Sansonetti authored
258 return RTEST(rb_vm_call(obj, selRespondToDefault, 2, args));
59fba25 Kernel#respond_to_missing?: added
Laurent Sansonetti authored
259 }
9e76215 fixed Module#method_defined?
Laurent Sansonetti authored
260 }
261 return true;
262 }
263
9c1d230 committing experimental branch content
Laurent Sansonetti authored
264 static VALUE
265 rb_mod_method_defined(VALUE mod, SEL sel, VALUE mid)
266 {
914ab2b fixed Module#method_defined?
Laurent Sansonetti authored
267 ID id = rb_to_id(mid);
9e76215 fixed Module#method_defined?
Laurent Sansonetti authored
268 return rb_obj_respond_to2(Qnil, mod, id, true, false) ? Qtrue : Qfalse;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
269 }
270
271 #define VISI_CHECK(x,f) (((x)&NOEX_MASK) == (f))
272
273 /*
274 * call-seq:
275 * mod.public_method_defined?(symbol) => true or false
276 *
277 * Returns +true+ if the named public method is defined by
278 * _mod_ (or its included modules and, if _mod_ is a class,
279 * its ancestors).
280 *
281 * module A
282 * def method1() end
283 * end
284 * class B
285 * protected
286 * def method2() end
287 * end
288 * class C < B
289 * include A
290 * def method3() end
291 * end
292 *
293 * A.method_defined? :method1 #=> true
294 * C.public_method_defined? "method1" #=> true
295 * C.public_method_defined? "method2" #=> false
296 * C.method_defined? "method2" #=> true
297 */
298
299 static VALUE
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
300 check_method_visibility(VALUE mod, ID id, int visi)
9c1d230 committing experimental branch content
Laurent Sansonetti authored
301 {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
302 rb_vm_method_node_t *node;
303 if (rb_vm_lookup_method2((Class)mod, id, NULL, NULL, &node)) {
304 if (node != NULL) {
305 if (node->flags & rb_vm_noex_flag(visi)) {
306 return Qtrue;
307 }
308 }
9c1d230 committing experimental branch content
Laurent Sansonetti authored
309 }
310 return Qfalse;
311 }
312
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
313 static VALUE
314 rb_mod_public_method_defined(VALUE mod, SEL sel, VALUE mid)
315 {
316 ID id = rb_to_id(mid);
317 return check_method_visibility(mod, id, NOEX_PUBLIC);
318 }
319
9c1d230 committing experimental branch content
Laurent Sansonetti authored
320 /*
321 * call-seq:
322 * mod.private_method_defined?(symbol) => true or false
323 *
324 * Returns +true+ if the named private method is defined by
325 * _ mod_ (or its included modules and, if _mod_ is a class,
326 * its ancestors).
327 *
328 * module A
329 * def method1() end
330 * end
331 * class B
332 * private
333 * def method2() end
334 * end
335 * class C < B
336 * include A
337 * def method3() end
338 * end
339 *
340 * A.method_defined? :method1 #=> true
341 * C.private_method_defined? "method1" #=> false
342 * C.private_method_defined? "method2" #=> true
343 * C.method_defined? "method2" #=> false
344 */
345
346 static VALUE
347 rb_mod_private_method_defined(VALUE mod, SEL sel, VALUE mid)
348 {
349 ID id = rb_to_id(mid);
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
350 return check_method_visibility(mod, id, NOEX_PRIVATE);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
351 }
352
353 /*
354 * call-seq:
355 * mod.protected_method_defined?(symbol) => true or false
356 *
357 * Returns +true+ if the named protected method is defined
358 * by _mod_ (or its included modules and, if _mod_ is a
359 * class, its ancestors).
360 *
361 * module A
362 * def method1() end
363 * end
364 * class B
365 * protected
366 * def method2() end
367 * end
368 * class C < B
369 * include A
370 * def method3() end
371 * end
372 *
373 * A.method_defined? :method1 #=> true
374 * C.protected_method_defined? "method1" #=> false
375 * C.protected_method_defined? "method2" #=> true
376 * C.method_defined? "method2" #=> true
377 */
378
379 static VALUE
380 rb_mod_protected_method_defined(VALUE mod, SEL sel, VALUE mid)
381 {
382 ID id = rb_to_id(mid);
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
383 return check_method_visibility(mod, id, NOEX_PROTECTED);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
384 }
385
386 void
387 rb_alias(VALUE klass, ID name, ID def)
388 {
389 rb_vm_alias(klass, name, def);
390 }
391
392 /*
393 * call-seq:
394 * alias_method(new_name, old_name) => self
395 *
396 * Makes <i>new_name</i> a new copy of the method <i>old_name</i>. This can
397 * be used to retain access to methods that are overridden.
398 *
399 * module Mod
400 * alias_method :orig_exit, :exit
401 * def exit(code=0)
402 * puts "Exiting with code #{code}"
403 * orig_exit(code)
404 * end
405 * end
406 * include Mod
407 * exit(99)
408 *
409 * <em>produces:</em>
410 *
411 * Exiting with code 99
412 */
413
414 static VALUE
415 rb_mod_alias_method(VALUE mod, SEL sel, VALUE newname, VALUE oldname)
416 {
417 rb_alias(mod, rb_to_id(newname), rb_to_id(oldname));
418 return mod;
419 }
420
421 static void
422 secure_visibility(VALUE self)
423 {
ed44bd9 @Watson1978 Module#public (and some method) with untrusted will not throw a Security...
Watson1978 authored
424 if (rb_safe_level() >= 4 && !OBJ_UNTRUSTED(self)) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
425 rb_raise(rb_eSecurityError,
426 "Insecure: can't change method visibility");
427 }
428 }
429
430 static void
431 set_method_visibility(VALUE self, int argc, VALUE *argv, ID ex)
432 {
433 secure_visibility(self);
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
434 for (int i = 0; i < argc; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
435 rb_export_method(self, rb_to_id(argv[i]), ex);
436 }
437 }
438
439 /*
440 * call-seq:
441 * public => self
442 * public(symbol, ...) => self
443 *
444 * With no arguments, sets the default visibility for subsequently
445 * defined methods to public. With arguments, sets the named methods to
446 * have public visibility.
447 */
448
449 static VALUE
450 rb_mod_public(VALUE module, SEL sel, int argc, VALUE *argv)
451 {
452 secure_visibility(module);
453 if (argc == 0) {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
454 rb_vm_set_current_scope(module, SCOPE_PUBLIC);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
455 }
456 else {
457 set_method_visibility(module, argc, argv, NOEX_PUBLIC);
458 }
459 return module;
460 }
461
462 /*
463 * call-seq:
464 * protected => self
465 * protected(symbol, ...) => self
466 *
467 * With no arguments, sets the default visibility for subsequently
468 * defined methods to protected. With arguments, sets the named methods
469 * to have protected visibility.
470 */
471
472 static VALUE
473 rb_mod_protected(VALUE module, SEL sel, int argc, VALUE *argv)
474 {
475 secure_visibility(module);
476 if (argc == 0) {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
477 rb_vm_set_current_scope(module, SCOPE_PROTECTED);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
478 }
479 else {
480 set_method_visibility(module, argc, argv, NOEX_PROTECTED);
481 }
482 return module;
483 }
484
485 /*
486 * call-seq:
487 * private => self
488 * private(symbol, ...) => self
489 *
490 * With no arguments, sets the default visibility for subsequently
491 * defined methods to private. With arguments, sets the named methods
492 * to have private visibility.
493 *
494 * module Mod
495 * def a() end
496 * def b() end
497 * private
498 * def c() end
499 * private :a
500 * end
501 * Mod.private_instance_methods #=> [:a, :c]
502 */
503
504 static VALUE
505 rb_mod_private(VALUE module, SEL sel, int argc, VALUE *argv)
506 {
507 secure_visibility(module);
508 if (argc == 0) {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
509 rb_vm_set_current_scope(module, SCOPE_PRIVATE);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
510 }
511 else {
512 set_method_visibility(module, argc, argv, NOEX_PRIVATE);
513 }
514 return module;
515 }
516
517 /*
518 * call-seq:
519 * mod.public_class_method(symbol, ...) => mod
520 *
521 * Makes a list of existing class methods public.
522 */
523
524 static VALUE
525 rb_mod_public_method(VALUE obj, SEL sel, int argc, VALUE *argv)
526 {
527 set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PUBLIC);
528 return obj;
529 }
530
531 /*
532 * call-seq:
533 * mod.private_class_method(symbol, ...) => mod
534 *
535 * Makes existing class methods private. Often used to hide the default
536 * constructor <code>new</code>.
537 *
538 * class SimpleSingleton # Not thread safe
539 * private_class_method :new
540 * def SimpleSingleton.create(*args, &block)
541 * @me = new(*args, &block) if ! @me
542 * @me
543 * end
544 * end
545 */
546
547 static VALUE
548 rb_mod_private_method(VALUE obj, SEL sel, int argc, VALUE *argv)
549 {
550 set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PRIVATE);
551 return obj;
552 }
553
554 /*
555 * call-seq:
556 * public
557 * public(symbol, ...)
558 *
559 * With no arguments, sets the default visibility for subsequently
560 * defined methods to public. With arguments, sets the named methods to
561 * have public visibility.
562 */
563
564 static VALUE
565 top_public(VALUE recv, SEL sel, int argc, VALUE *argv)
566 {
567 return rb_mod_public(rb_cObject, 0, argc, argv);
568 }
569
570 static VALUE
571 top_private(VALUE recv, SEL sel, int argc, VALUE *argv)
572 {
573 return rb_mod_private(rb_cObject, 0, argc, argv);
574 }
575
576 /*
577 * call-seq:
578 * module_function(symbol, ...) => self
579 *
580 * Creates module functions for the named methods. These functions may
581 * be called with the module as a receiver, and also become available
582 * as instance methods to classes that mix in the module. Module
583 * functions are copies of the original, and so may be changed
584 * independently. The instance-method versions are made private. If
585 * used with no arguments, subsequently defined methods become module
586 * functions.
587 *
588 * module Mod
589 * def one
590 * "This is one"
591 * end
592 * module_function :one
593 * end
594 * class Cls
595 * include Mod
596 * def callOne
597 * one
598 * end
599 * end
600 * Mod.one #=> "This is one"
601 * c = Cls.new
602 * c.callOne #=> "This is one"
603 * module Mod
604 * def one
605 * "This is the new one"
606 * end
607 * end
608 * Mod.one #=> "This is one"
609 * c.callOne #=> "This is the new one"
610 */
611
612 static VALUE
613 rb_mod_modfunc(VALUE module, SEL sel, int argc, VALUE *argv)
614 {
615 if (TYPE(module) != T_MODULE) {
616 rb_raise(rb_eTypeError, "module_function must be called for modules");
617 }
618
619 secure_visibility(module);
620 if (argc == 0) {
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
621 rb_vm_set_current_scope(module, SCOPE_MODULE_FUNC);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
622 return module;
623 }
624
625 set_method_visibility(module, argc, argv, NOEX_PRIVATE);
626
9590d40 fixing and adding several missing ruby method features
Laurent Sansonetti authored
627 for (int i = 0; i < argc; i++) {
9c1d230 committing experimental branch content
Laurent Sansonetti authored
628 ID id = rb_to_id(argv[i]);
629 IMP imp;
69ef419 added AOT compilation support for method definitions and constants
Laurent Sansonetti authored
630 rb_vm_method_node_t *node;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
631 SEL sel;
632
633 if (!rb_vm_lookup_method2((Class)module, id, &sel, &imp, &node)) {
634 // Methods are checked in set_method_visibility().
635 rb_bug("undefined method `%s'; can't happen", rb_id2name(id));
636 }
637
846054c when changing the visibility of a method that is included in classes, ma...
Laurent Sansonetti authored
638 rb_vm_define_method2(*(Class *)module, sel, node, -1, false);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
639 }
640
641 return module;
642 }
643
644 /*
645 * call-seq:
646 * obj.respond_to?(symbol, include_private=false) => true or false
647 *
59fba25 Kernel#respond_to_missing?: added
Laurent Sansonetti authored
648 * Returns +true+ if _obj_ responds to the given
9c1d230 committing experimental branch content
Laurent Sansonetti authored
649 * method. Private methods are included in the search only if the
650 * optional second parameter evaluates to +true+.
59fba25 Kernel#respond_to_missing?: added
Laurent Sansonetti authored
651 *
652 * If the method is not implemented,
653 * as Process.fork on Windows, File.lchmod on GNU/Linux, etc.,
654 * false is returned.
655 *
656 * If the method is not defined, <code>respond_to_missing?</code>
657 * method is called and the result is returned.
9c1d230 committing experimental branch content
Laurent Sansonetti authored
658 */
659
468a2ea Move Obj-C related headers around.
Thibault Martin-Lagardette authored
660 int
661 rb_obj_respond_to(VALUE obj, ID id, int priv)
28db598 make sure Kernel#respond_to? doesn't call itself stupid^Wrecursively
Laurent Sansonetti authored
662 {
9e76215 fixed Module#method_defined?
Laurent Sansonetti authored
663 return rb_obj_respond_to2(obj, Qnil, id, priv, true);
28db598 make sure Kernel#respond_to? doesn't call itself stupid^Wrecursively
Laurent Sansonetti authored
664 }
665
468a2ea Move Obj-C related headers around.
Thibault Martin-Lagardette authored
666 int
9c1d230 committing experimental branch content
Laurent Sansonetti authored
667 rb_respond_to(VALUE obj, ID id)
668 {
28db598 make sure Kernel#respond_to? doesn't call itself stupid^Wrecursively
Laurent Sansonetti authored
669 return rb_obj_respond_to(obj, id, false);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
670 }
671
672 static VALUE
673 obj_respond_to(VALUE obj, SEL sel, int argc, VALUE *argv)
674 {
675 VALUE mid, priv;
676 ID id;
677
678 rb_scan_args(argc, argv, "11", &mid, &priv);
679 id = rb_to_id(mid);
9e76215 fixed Module#method_defined?
Laurent Sansonetti authored
680 return rb_obj_respond_to2(obj, Qnil, id, RTEST(priv), false) ? Qtrue : Qfalse;
9c1d230 committing experimental branch content
Laurent Sansonetti authored
681 }
682
59fba25 Kernel#respond_to_missing?: added
Laurent Sansonetti authored
683 /*
684 * call-seq:
685 * obj.respond_to_missing?(symbol, include_private) => true or false
686 *
687 * Hook method to return whether the _obj_ can respond to _id_ method
688 * or not.
689 *
690 * See #respond_to?.
691 */
692
693 static VALUE
694 obj_respond_to_missing(VALUE obj, SEL sel, VALUE sym, VALUE priv)
695 {
696 return Qfalse;
697 }
698
9c1d230 committing experimental branch content
Laurent Sansonetti authored
699 IMP basic_respond_to_imp = NULL;
700
701 void
702 Init_eval_method(void)
703 {
704 rb_objc_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1);
59fba25 Kernel#respond_to_missing?: added
Laurent Sansonetti authored
705 rb_objc_define_method(rb_mKernel, "respond_to_missing?", obj_respond_to_missing, 2);
706 selRespondToDefault = sel_registerName("respond_to_missing?:");
707 basic_respond_to_imp = class_getMethodImplementation((Class)rb_mKernel,
708 selRespondTo);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
709
710 rb_objc_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
711 rb_objc_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
712 rb_objc_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
713 rb_objc_define_private_method(rb_cModule, "public", rb_mod_public, -1);
714 rb_objc_define_private_method(rb_cModule, "protected", rb_mod_protected, -1);
715 rb_objc_define_private_method(rb_cModule, "private", rb_mod_private, -1);
716 rb_objc_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
717
718 rb_objc_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
59fba25 Kernel#respond_to_missing?: added
Laurent Sansonetti authored
719 rb_objc_define_method(rb_cModule, "public_method_defined?",
720 rb_mod_public_method_defined, 1);
721 rb_objc_define_method(rb_cModule, "private_method_defined?",
722 rb_mod_private_method_defined, 1);
723 rb_objc_define_method(rb_cModule, "protected_method_defined?",
724 rb_mod_protected_method_defined, 1);
9c1d230 committing experimental branch content
Laurent Sansonetti authored
725 rb_objc_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
726 rb_objc_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
727
728 VALUE cTopLevel = *(VALUE *)rb_vm_top_self();
729 rb_objc_define_method(cTopLevel, "public", top_public, -1);
730 rb_objc_define_method(cTopLevel, "private", top_private, -1);
731
732 object_id = rb_intern("object_id");
733 __send__ = rb_intern("__send__");
734 eqq = rb_intern("===");
735 each = rb_intern("each");
736 aref = rb_intern("[]");
737 aset = rb_intern("[]=");
738 match = rb_intern("=~");
739 missing = rb_intern("method_missing");
740 added = rb_intern("method_added");
741 singleton_added = rb_intern("singleton_method_added");
742 removed = rb_intern("method_removed");
743 singleton_removed = rb_intern("singleton_method_removed");
744 undefined = rb_intern("method_undefined");
745 singleton_undefined = rb_intern("singleton_method_undefined");
746 }
747
Something went wrong with that request. Please try again.